1 karl 1.52 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.13 //
|
3 karl 1.44 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.40 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.44 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.46 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.52 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.26 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.13 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.52 //
|
21 kumpf 1.26 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.26 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.13 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
|
34 kumpf 1.29 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
|
35 david.dillard 1.45 // (carolann_graves@hp.com)
36 // David Dillard, VERITAS Software Corp.
37 // (david.dillard@veritas.com)
|
38 mike 1.13 //
39 //%/////////////////////////////////////////////////////////////////////////////
40
41 #include <cstdio>
|
42 kumpf 1.19 #include "CIMPropertyRep.h"
|
43 mike 1.13 #include "Indentor.h"
44 #include "CIMName.h"
45 #include "CIMScope.h"
|
46 kumpf 1.25 #include "XmlWriter.h"
47 #include "MofWriter.h"
|
48 a.dunfey 1.42 #include "DeclContext.h"
|
49 mike 1.51 #include "StrLit.h"
|
50 mike 1.13
|
51 mike 1.17 PEGASUS_USING_STD;
52
|
53 mike 1.13 PEGASUS_NAMESPACE_BEGIN
54
|
55 chip 1.48 CIMPropertyRep::CIMPropertyRep()
56 {
57 }
58
59 CIMPropertyRep::CIMPropertyRep(
60 const CIMPropertyRep& x,
61 Boolean propagateQualifiers)
62 :
63 Sharable(),
64 _name(x._name),
65 _value(x._value),
66 _arraySize(x._arraySize),
67 _referenceClassName(x._referenceClassName),
68 _classOrigin(x._classOrigin),
69 _propagated(x._propagated)
70 {
71 if (propagateQualifiers)
72 x._qualifiers.cloneTo(_qualifiers);
73 }
74
|
75 mike 1.13 CIMPropertyRep::CIMPropertyRep(
|
76 kumpf 1.30 const CIMName& name,
|
77 mike 1.13 const CIMValue& value,
78 Uint32 arraySize,
|
79 kumpf 1.30 const CIMName& referenceClassName,
80 const CIMName& classOrigin,
|
81 chip 1.48 Boolean propagated)
|
82 mike 1.17 :
|
83 mike 1.13 _name(name), _value(value), _arraySize(arraySize),
84 _referenceClassName(referenceClassName), _classOrigin(classOrigin),
85 _propagated(propagated)
86 {
|
87 chip 1.48 // ensure name is not null
88 if(name.isNull())
89 {
90 throw UninitializedObjectException();
91 }
92
93 if((arraySize != 0) && (!value.isArray() || value.getArraySize() != arraySize))
94 {
|
95 kumpf 1.38 throw TypeMismatchException();
|
96 chip 1.48 }
|
97 mike 1.13
|
98 kumpf 1.49 // A CIM Property may not be of reference array type
99 if (value.isArray() && (value.getType() == CIMTYPE_REFERENCE))
100 {
101 throw TypeMismatchException();
102 }
103
|
104 chip 1.48 // if referenceClassName exists, must be CIMType REFERENCE.
|
105 kumpf 1.30 if (!referenceClassName.isNull())
|
106 mike 1.13 {
|
107 kumpf 1.30 if (_value.getType() != CIMTYPE_REFERENCE)
|
108 chip 1.48 {
|
109 kumpf 1.38 throw TypeMismatchException();
|
110 chip 1.48 }
|
111 kumpf 1.30 }
|
112 kumpf 1.41
113 // Can a property be of reference type with a null referenceClassName?
114 // The DMTF says yes if it is a property of an instance; no if it is a
115 // property of a class. We'll allow it here, but check in the CIMClass
116 // addProperty() method.
|
117 mike 1.13 }
118
119 CIMPropertyRep::~CIMPropertyRep()
120 {
121 }
122
|
123 kumpf 1.30 void CIMPropertyRep::setName(const CIMName& name)
|
124 mike 1.13 {
|
125 chip 1.48 // ensure name is not null
126 if(name.isNull())
127 {
128 throw UninitializedObjectException();
129 }
130
|
131 mike 1.13 _name = name;
132 }
133
|
134 kumpf 1.30 void CIMPropertyRep::setClassOrigin(const CIMName& classOrigin)
|
135 mike 1.13 {
136 _classOrigin = classOrigin;
137 }
138
139 void CIMPropertyRep::resolve(
140 DeclContext* declContext,
|
141 kumpf 1.30 const CIMNamespaceName& nameSpace,
|
142 mike 1.13 Boolean isInstancePart,
|
143 mike 1.17 const CIMConstProperty& inheritedProperty,
144 Boolean propagateQualifiers)
|
145 mike 1.13 {
|
146 kumpf 1.32 PEGASUS_ASSERT(!inheritedProperty.isUninitialized());
|
147 mike 1.13
148 // Check the type:
149
150 if (!inheritedProperty.getValue().typeCompatible(_value))
|
151 dave.sudlik 1.47 {
152 if (!(
153 (inheritedProperty.getValue().getType() == CIMTYPE_OBJECT) &&
154 (_value.getType() == CIMTYPE_STRING) &&
155 (_qualifiers.find(CIMName("EmbeddedObject")) != PEG_NOT_FOUND) &&
156 (inheritedProperty.getValue().isArray() == _value.isArray())
157 ))
158 {
159 throw TypeMismatchException();
160 }
161 }
|
162 mike 1.13
163 // Validate the qualifiers of the property (according to
164 // superClass's property with the same name). This method
165 // will throw an exception if the validation fails.
166
|
167 kumpf 1.35 CIMScope scope = CIMScope::PROPERTY;
|
168 mike 1.13
|
169 kumpf 1.29 if (_value.getType() == CIMTYPE_REFERENCE)
|
170 kumpf 1.35 scope = CIMScope::REFERENCE;
|
171 mike 1.13
|
172 a.dunfey 1.42 // Test the reference class name against the inherited property
|
173 kumpf 1.41 if (_value.getType() == CIMTYPE_REFERENCE)
174 {
|
175 a.dunfey 1.43 CIMName inheritedReferenceClassName = inheritedProperty.getReferenceClassName();
176 CIMName referenceClassName;
177 if(!_referenceClassName.isNull() && !_value.isNull())
178 {
179 CIMObjectPath valuePath;
180 _value.get(valuePath);
181 referenceClassName = valuePath.getClassName();
182 bool found = _referenceClassName.equal(referenceClassName);
183 while(!found)
184 {
185 CIMClass referenceClass = declContext->lookupClass(nameSpace, referenceClassName);
186 if(referenceClass.isUninitialized())
187 {
188 throw PEGASUS_CIM_EXCEPTION(
189 CIM_ERR_NOT_FOUND, referenceClassName.getString());
190 }
191 referenceClassName = referenceClass.getSuperClassName();
192 if(referenceClassName.isNull())
193 throw TypeMismatchException();
194
195 found = inheritedReferenceClassName.equal(referenceClassName);
196 a.dunfey 1.43 }
197 }
198 else if(!_referenceClassName.isNull())
199 {
200 referenceClassName = _referenceClassName;
201 }
202 else if(!_value.isNull())
203 {
204 CIMObjectPath valuePath;
205 _value.get(valuePath);
206 referenceClassName = valuePath.getClassName();
207 }
|
208 a.dunfey 1.42
|
209 a.dunfey 1.43 if(!referenceClassName.isNull())
210 {
211 bool found = inheritedReferenceClassName.equal(referenceClassName);
212 while(!found)
213 {
214 CIMClass referenceClass = declContext->lookupClass(nameSpace, referenceClassName);
215 if(referenceClass.isUninitialized())
216 {
217 throw PEGASUS_CIM_EXCEPTION(
218 CIM_ERR_NOT_FOUND, referenceClassName.getString());
219 }
220 referenceClassName = referenceClass.getSuperClassName();
221 if(referenceClassName.isNull())
222 throw TypeMismatchException();
223
224 found = inheritedReferenceClassName.equal(referenceClassName);
225 }
226 }
|
227 kumpf 1.41 }
228
|
229 mike 1.13 _qualifiers.resolve(
230 declContext,
231 nameSpace,
232 scope,
233 isInstancePart,
|
234 chip 1.48 inheritedProperty._rep->_qualifiers,
|
235 mike 1.17 propagateQualifiers);
|
236 mike 1.13
237 _classOrigin = inheritedProperty.getClassOrigin();
238 }
239
240 void CIMPropertyRep::resolve(
241 DeclContext* declContext,
|
242 kumpf 1.30 const CIMNamespaceName& nameSpace,
|
243 mike 1.17 Boolean isInstancePart,
|
244 kumpf 1.28 Boolean propagateQualifiers)
|
245 mike 1.13 {
246 CIMQualifierList dummy;
247
|
248 kumpf 1.35 CIMScope scope = CIMScope::PROPERTY;
|
249 mike 1.13
|
250 kumpf 1.29 if (_value.getType() == CIMTYPE_REFERENCE)
|
251 kumpf 1.35 scope = CIMScope::REFERENCE;
|
252 mike 1.13
253 _qualifiers.resolve(
254 declContext,
255 nameSpace,
256 scope,
257 isInstancePart,
|
258 mike 1.17 dummy,
|
259 kumpf 1.28 propagateQualifiers);
|
260 mike 1.13 }
261
262 static const char* _toString(Boolean x)
263 {
264 return x ? "true" : "false";
265 }
266
|
267 mike 1.50 void CIMPropertyRep::toXml(Buffer& out) const
|
268 mike 1.13 {
269 if (_value.isArray())
270 {
|
271 mike 1.51 out << STRLIT("<PROPERTY.ARRAY NAME=\"") << _name << STRLIT("\" ");
|
272 mike 1.13
|
273 chip 1.48 // If the property array type is CIMObject, then
|
274 dave.sudlik 1.47 // encode the property in CIM-XML as a string array with the EMBEDDEDOBJECT attribute
275 // (there is not currently a CIM-XML "object" datatype)
276 // else
277 // output the real type
278 if (_value.getType() == CIMTYPE_OBJECT)
279 {
280 Array<CIMObject> a;
281 _value.get(a);
|
282 mike 1.51 out << STRLIT(" TYPE=\"string\"");
|
283 dave.sudlik 1.47 // If the Embedded Object is an instance, always add the EMBEDDEDOBJECT attribute.
284 if (a.size() > 0 && a[0].isInstance())
|
285 mike 1.51 out << STRLIT(" EMBEDDEDOBJECT=\"object\"");
|
286 dave.sudlik 1.47 // Else the Embedded Object is a class, always add the EmbeddedObject qualifier.
287 // Note that if the macro PEGASUS_SNIA_INTEROP_COMPATIBILITY is defined, then
288 // the EmbeddedObject qualifier will always be added, whether it's a class or
289 // an instance.
290 #ifndef PEGASUS_SNIA_INTEROP_COMPATIBILITY
291 else
292 {
293 #endif
294 if (_qualifiers.find(CIMName("EmbeddedObject")) == PEG_NOT_FOUND)
295 {
296 // Note that _qualifiers is not defined as const, and neither is add(),
297 // but this method toXml() *is* const. However, in this case we really
298 // do want to add the EmbeddedObject qualifier, so we cast away the
299 // implied const-ness of _qualifiers.
300 ((CIMQualifierList)_qualifiers).add(CIMQualifier(CIMName("EmbeddedObject"), true));
301 }
302 #ifndef PEGASUS_SNIA_INTEROP_COMPATIBILITY
303 }
304 #endif
305 }
306 else
307 dave.sudlik 1.47 {
|
308 mike 1.51 out << STRLIT(" TYPE=\"") << cimTypeToString(_value.getType ());
309 out.append('"');
|
310 dave.sudlik 1.47 }
|
311 mike 1.13
|
312 dave.sudlik 1.47 if (_arraySize)
|
313 mike 1.13 {
314 char buffer[32];
315 sprintf(buffer, "%d", _arraySize);
|
316 mike 1.51 out << STRLIT(" ARRAYSIZE=\"") << buffer;
317 out.append('"');
|
318 mike 1.13 }
319
|
320 kumpf 1.30 if (!_classOrigin.isNull())
|
321 mike 1.51 {
322 out << STRLIT(" CLASSORIGIN=\"") << _classOrigin;
323 out.append('"');
324 }
|
325 mike 1.13
326 if (_propagated != false)
|
327 mike 1.51 {
328 out << STRLIT(" PROPAGATED=\"") << _toString(_propagated);
329 out.append('"');
330 }
|
331 mike 1.13
|
332 mike 1.51 out << STRLIT(">\n");
|
333 mike 1.13
334 _qualifiers.toXml(out);
335
|
336 kumpf 1.23 XmlWriter::appendValueElement(out, _value);
|
337 mike 1.13
|
338 mike 1.51 out << STRLIT("</PROPERTY.ARRAY>\n");
|
339 mike 1.13 }
|
340 kumpf 1.29 else if (_value.getType() == CIMTYPE_REFERENCE)
|
341 mike 1.13 {
|
342 mike 1.51 out << STRLIT("<PROPERTY.REFERENCE");
|
343 mike 1.13
|
344 mike 1.51 out << STRLIT(" NAME=\"") << _name << STRLIT("\" ");
|
345 mike 1.13
|
346 kumpf 1.41 if (!_referenceClassName.isNull())
347 {
|
348 mike 1.51 out << STRLIT(" REFERENCECLASS=\"") << _referenceClassName;
349 out.append('"');
|
350 kumpf 1.41 }
|
351 mike 1.13
|
352 kumpf 1.30 if (!_classOrigin.isNull())
|
353 mike 1.51 {
354 out << STRLIT(" CLASSORIGIN=\"") << _classOrigin;
355 out.append('"');
356 }
|
357 mike 1.13
358 if (_propagated != false)
|
359 mike 1.51 {
360 out << STRLIT(" PROPAGATED=\"") << _toString(_propagated);
361 out.append('"');
362 }
|
363 mike 1.13
|
364 mike 1.51 out << STRLIT(">\n");
|
365 mike 1.13
366 _qualifiers.toXml(out);
|
367 chip 1.48
|
368 kumpf 1.23 XmlWriter::appendValueElement(out, _value);
|
369 mike 1.13
|
370 mike 1.51 out << STRLIT("</PROPERTY.REFERENCE>\n");
|
371 mike 1.13 }
372 else
373 {
|
374 mike 1.51 out << STRLIT("<PROPERTY NAME=\"") << _name << STRLIT("\" ");
|
375 mike 1.13
|
376 kumpf 1.30 if (!_classOrigin.isNull())
|
377 mike 1.51 {
378 out << STRLIT(" CLASSORIGIN=\"") << _classOrigin;
379 out.append('"');
380 }
|
381 mike 1.13
382 if (_propagated != false)
|
383 mike 1.51 {
384 out << STRLIT(" PROPAGATED=\"") << _toString(_propagated);
385 out.append('"');
386 }
|
387 mike 1.13
|
388 chip 1.48 // If the property type is CIMObject, then
|
389 dave.sudlik 1.47 // encode the property in CIM-XML as a string with the EMBEDDEDOBJECT attribute
390 // (there is not currently a CIM-XML "object" datatype)
391 // else
392 // output the real type
393 if (_value.getType() == CIMTYPE_OBJECT)
394 {
395 CIMObject a;
396 _value.get(a);
|
397 mike 1.51 out << STRLIT(" TYPE=\"string\"");
|
398 dave.sudlik 1.47 // If the Embedded Object is an instance, always add the EMBEDDEDOBJECT attribute.
399 if (a.isInstance())
|
400 mike 1.51 out << STRLIT(" EMBEDDEDOBJECT=\"object\"");
|
401 dave.sudlik 1.47 // Else the Embedded Object is a class, always add the EmbeddedObject qualifier.
402 // Note that if the macro PEGASUS_SNIA_INTEROP_COMPATIBILITY is defined, then
403 // the EmbeddedObject qualifier will always be added, whether it's a class or
404 // an instance.
405 #ifndef PEGASUS_SNIA_INTEROP_COMPATIBILITY
406 else
407 {
408 #endif
409 if (_qualifiers.find(CIMName("EmbeddedObject")) == PEG_NOT_FOUND)
410 {
411 // Note that _qualifiers is not defined as const, and neither is add(),
412 // but this method toXml() *is* const. However, in this case we really
413 // do want to add the EmbeddedObject qualifier, so we cast away the
414 // implied const-ness of _qualifiers.
415 ((CIMQualifierList)_qualifiers).add(CIMQualifier(CIMName("EmbeddedObject"), true));
416 }
417 #ifndef PEGASUS_SNIA_INTEROP_COMPATIBILITY
418 }
419 #endif
420 }
421 else
422 dave.sudlik 1.47 {
|
423 mike 1.51 out << STRLIT(" TYPE=\"") << cimTypeToString(_value.getType());
424 out.append('"');
|
425 dave.sudlik 1.47 }
|
426 mike 1.13
|
427 mike 1.51 out << STRLIT(">\n");
|
428 mike 1.13
429 _qualifiers.toXml(out);
|
430 chip 1.48
|
431 kumpf 1.23 XmlWriter::appendValueElement(out, _value);
|
432 mike 1.13
|
433 mike 1.51 out << STRLIT("</PROPERTY>\n");
|
434 mike 1.13 }
435 }
436
|
437 mike 1.14 /** toMof - returns the MOF for the CIM Property Object in the parameter.
438 The BNF for the property MOF is:
439 <pre>
440 propertyDeclaration = [ qualifierList ] dataType propertyName
441 [ array ] [ defaultValue ] ";"
|
442 chip 1.48
|
443 mike 1.14 array = "[" [positiveDecimalValue] "]"
|
444 chip 1.48
|
445 mike 1.14 defaultValue = "=" initializer
446 </pre>
447 Format with qualifiers on one line and declaration on another. Start
448 with newline but none at the end.
449 */
|
450 mike 1.50 void CIMPropertyRep::toMof(Buffer& out) const //ATTNKS:
|
451 mike 1.14 {
452 //Output the qualifier list
453 if (_qualifiers.getCount())
|
454 mike 1.51 out.append('\n');
|
455 mike 1.14 _qualifiers.toMof(out);
456
457 // Output the Type and name on a new line
|
458 mike 1.51 out << '\n' << cimTypeToString(_value.getType ());
459 out.append(' ');
460 out << _name;
|
461 mike 1.14
462 // If array put the Array indicator "[]" and possible size after name.
463 if (_value.isArray())
464 {
465 if (_arraySize)
466 {
467 char buffer[32];
|
468 mike 1.51 int n = sprintf(buffer, "[%d]", _arraySize);
469 out.append(buffer, n);
|
470 mike 1.14 }
471 else
|
472 mike 1.51 out << STRLIT("[]");
|
473 mike 1.14 }
474
475 // If the property value is not Null, add value after "="
476 if (!_value.isNull())
477 {
|
478 mike 1.51 out << STRLIT(" = ");
|
479 mike 1.14 if (_value.isArray())
|
480 chip 1.48 {
|
481 mike 1.14 // Insert any property values
|
482 kumpf 1.25 MofWriter::appendValueElement(out, _value);
|
483 mike 1.14 }
|
484 kumpf 1.29 else if (_value.getType() == CIMTYPE_REFERENCE)
|
485 mike 1.14 {
|
486 kumpf 1.25 MofWriter::appendValueElement(out, _value);
|
487 mike 1.14 }
488 else
|
489 chip 1.48 {
|
490 kumpf 1.25 MofWriter::appendValueElement(out, _value);
|
491 mike 1.14 }
492 }
493 // Close the property MOF
|
494 mike 1.51 out.append(';');
|
495 mike 1.14
496 }
497
|
498 mike 1.13 Boolean CIMPropertyRep::identical(const CIMPropertyRep* x) const
499 {
|
500 kumpf 1.39 if (!_name.equal (x->_name))
|
501 mike 1.13 return false;
502
503 if (_value != x->_value)
504 return false;
505
|
506 kumpf 1.39 if (!_referenceClassName.equal (x->_referenceClassName))
|
507 mike 1.13 return false;
508
509 if (!_qualifiers.identical(x->_qualifiers))
510 return false;
511
|
512 kumpf 1.39 if (!_classOrigin.equal (x->_classOrigin))
|
513 mike 1.13 return false;
514
515 if (_propagated != x->_propagated)
516 return false;
517
518 return true;
519 }
520
521 void CIMPropertyRep::setValue(const CIMValue& value)
522 {
523 // CIMType of value is immutable:
524
525 if (!value.typeCompatible(_value))
|
526 kumpf 1.38 throw TypeMismatchException();
|
527 mike 1.13
528 if (_arraySize && _arraySize != value.getArraySize())
|
529 kumpf 1.38 throw TypeMismatchException();
|
530 mike 1.13
|
531 kumpf 1.49 // A CIM Property may not be of reference array type
532 if (value.isArray() && (value.getType() == CIMTYPE_REFERENCE))
533 {
534 throw TypeMismatchException();
535 }
536
|
537 mike 1.13 _value = value;
538 }
539
540 PEGASUS_NAMESPACE_END
|