1 mike 1.18 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 chip 1.21 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
9 mike 1.18 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
|
11 chip 1.21 //
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
13 mike 1.18 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
14 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
15 chip 1.21 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
18 mike 1.18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 //==============================================================================
22 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
|
25 kumpf 1.35 // Modified By: Karl Schopmeyer(k.schopmeyer@attglobal.net)
26 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
27 mike 1.18 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
|
30 kumpf 1.34 #include "CIMClassRep.h"
|
31 mike 1.18 #include "DeclContext.h"
32 #include "Indentor.h"
33 #include "CIMName.h"
34 #include "CIMQualifierNames.h"
35 #include "XmlWriter.h"
|
36 karl 1.30 #include <Pegasus/Common/Tracer.h>
|
37 mike 1.18
38 PEGASUS_NAMESPACE_BEGIN
|
39 karl 1.29 PEGASUS_USING_STD;
|
40 mike 1.18
41 CIMClassRep::CIMClassRep(
|
42 chip 1.23 const CIMReference& reference,
|
43 chip 1.21 const String& superClassName)
|
44 mike 1.20 :
|
45 chip 1.23 CIMObjectRep(reference),
|
46 mike 1.20 _superClassName(superClassName)
|
47 mike 1.18 {
48 if (superClassName.size() && !CIMName::legal(superClassName))
49 throw IllegalName();
50 }
51
52 CIMClassRep::~CIMClassRep()
53 {
54
55 }
56
57 Boolean CIMClassRep::isAssociation() const
58 {
59 Uint32 pos = findQualifier(CIMQualifierNames::ASSOCIATION);
60
61 if (pos == PEG_NOT_FOUND)
62 return false;
63
64 Boolean flag;
65
66 const CIMValue& value = getQualifier(pos).getValue();
67
68 mike 1.18 if (value.getType() != CIMType::BOOLEAN)
69 return false;
70
71 value.get(flag);
72 return flag;
73 }
74
75 Boolean CIMClassRep::isAbstract() const
76 {
77 Uint32 pos = findQualifier(CIMQualifierNames::ABSTRACT);
78
79 if (pos == PEG_NOT_FOUND)
80 return false;
81
82 Boolean flag;
83 const CIMValue& value = getQualifier(pos).getValue();
84
85 if (value.getType() != CIMType::BOOLEAN)
86 return false;
87
88 value.get(flag);
89 mike 1.18 return flag;
90 }
91
|
92 karl 1.30 Boolean CIMClassRep::isTrueQualifier(const String& name) const
93 {
94 Uint32 pos = findQualifier(name);
95
96 if (pos == PEG_NOT_FOUND)
97 return false;
98
99 Boolean flag;
100 const CIMValue& value = getQualifier(pos).getValue();
101
102 if (value.getType() != CIMType::BOOLEAN)
103 return false;
104
105 value.get(flag);
106 return flag;
107 }
108
|
109 mike 1.18 void CIMClassRep::setSuperClassName(const String& superClassName)
110 {
111 if (!CIMName::legal(superClassName))
112 throw IllegalName();
113
114 _superClassName = superClassName;
115 }
116
117 void CIMClassRep::addProperty(const CIMProperty& x)
118 {
119 if (!x)
120 throw UnitializedHandle();
121
122 // Reject addition of duplicate property name:
123
124 if (findProperty(x.getName()) != PEG_NOT_FOUND)
125 throw AlreadyExists();
126
127 // Reject addition of references to non-associations:
128
129 if (!isAssociation() && x.getValue().getType() == CIMType::REFERENCE)
|
130 chip 1.23 throw AddedReferenceToClass(_reference.getClassName());
|
131 mike 1.18
132 // Set the class origin:
133 // ATTN: put this check in other places:
134
135 if (x.getClassOrigin().size() == 0)
|
136 chip 1.23 CIMProperty(x).setClassOrigin(_reference.getClassName());
|
137 mike 1.18
138 // Add the property:
139
140 _properties.append(x);
141 }
142
143 void CIMClassRep::addMethod(const CIMMethod& x)
144 {
145 if (!x)
146 throw UnitializedHandle();
147
148 // Reject duplicate method names:
149
150 if (findMethod(x.getName()) != PEG_NOT_FOUND)
151 throw AlreadyExists();
152
153 // Add the method:
154
155 _methods.append(x);
156 }
157
|
158 kumpf 1.33 Uint32 CIMClassRep::findMethod(const String& name) const
|
159 mike 1.18 {
160 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
161 {
162 if (CIMName::equal(_methods[i].getName(), name))
163 return i;
164 }
165
166 return PEG_NOT_FOUND;
167 }
168
|
169 kumpf 1.33 Boolean CIMClassRep::existsMethod(const String& name) const
|
170 mike 1.18 {
|
171 mike 1.20 return(findMethod(name) == PEG_NOT_FOUND) ? false : true;
|
172 mike 1.18 }
|
173 mike 1.20
|
174 mike 1.18 CIMMethod CIMClassRep::getMethod(Uint32 pos)
175 {
176 if (pos >= _methods.size())
177 throw OutOfBounds();
178
179 return _methods[pos];
180 }
181
182 Uint32 CIMClassRep::getMethodCount() const
183 {
184 return _methods.size();
185 }
|
186 mike 1.20
|
187 mike 1.18 void CIMClassRep::removeMethod(Uint32 pos)
188 {
189 if (pos >= _methods.size())
190 throw OutOfBounds();
191
192 _methods.remove(pos);
193 }
194
195 void CIMClassRep::resolve(
196 DeclContext* context,
197 const String& nameSpace)
198 {
|
199 karl 1.30 PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMClassRep::resolve()");
|
200 mike 1.18 #if 0
201 if (_resolved)
|
202 chip 1.23 throw ClassAlreadyResolved(_reference.getClassName());
|
203 mike 1.18 #endif
204 if (!context)
205 throw NullPointer();
206
|
207 kumpf 1.32 PEG_TRACE_STRING(TRC_OBJECTRESOLUTION, Tracer::LEVEL3,
208 String("CIMClassRep::resolve class = ") +
209 _reference.getClassName() + ", superclass = " +
210 _superClassName);
|
211 karl 1.30
|
212 mike 1.18 if (_superClassName.size())
|
213 karl 1.29 {
214 //cout << "KSTEST Class Resolve with Super class " << getClassName()
215 //<< " superClass " << _superClassName << endl;
216 //----------------------------------------------------------------------
217 // First check to see if the super-class really exists and the subclassing legal:
218 //----------------------------------------------------------------------
219 CIMConstClass superClass
220 = context->lookupClass(nameSpace, _superClassName);
221
222 if (!superClass)
223 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_SUPERCLASS,_superClassName);
224
|
225 mike 1.18 #if 0
|
226 karl 1.29 if (!superClass._rep->_resolved)
227 throw ClassNotResolved(_superClassName);
|
228 mike 1.18 #endif
|
229 karl 1.29 // If subclass is abstract but superclass not, throw CIM Exception
230
231 /* ATTN:KS-24 Mar 2002 P1 - Test this and confirm that rule is correct
232 if isAbstract() && !superclass.isAbstract()
233 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_SUPERCLASS,_superClassName);
234 */
|
235 karl 1.31 /*if(superclass.isTrueQualifier(CIMQualifierNames::TERMINAL)
236 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_SUPERCLASS,_superClassName);
237 */
|
238 karl 1.29 //----------------------------------------------------------------------
239 // Iterate all the properties of *this* class. Resolve each one and
240 // set the class-origin:
241 //----------------------------------------------------------------------
242
243 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
244 {
245 CIMProperty& property = _properties[i];
246 Uint32 pos = superClass.findProperty(property.getName());
247
248 if (pos == PEG_NOT_FOUND)
249 {
250 property.resolve(context, nameSpace, false, true);
251 }
252 else
|
253 karl 1.28 {
|
254 karl 1.29 CIMConstProperty superClassProperty =
255 superClass.getProperty(pos);
256 property.resolve(
257 context, nameSpace, false, superClassProperty, true);
|
258 karl 1.28 }
|
259 karl 1.29 }
260
261 //----------------------------------------------------------------------
262 // Now prepend all properties inherited from the super-class (that
263 // are not overriden by this sub-class).
264 //----------------------------------------------------------------------
265
266 // Iterate super-class properties:
267
268 for (Uint32 i = 0, m = 0, n = superClass.getPropertyCount(); i < n; i++)
|
269 karl 1.28 {
|
270 karl 1.29 CIMConstProperty superClassProperty = superClass.getProperty(i);
271
272 // Find the property in *this* class; if not found, then clone and
273 // insert it (setting the propagated flag). Otherwise, change
274 // the class-origin and propagated flag accordingly.
275
276 Uint32 pos = PEG_NOT_FOUND;
277 /* ATTN: KS move to simpler version of the find
278 for (Uint32 j = m, n = _properties.size(); j < n; j++)
|
279 karl 1.28 {
|
280 karl 1.29 if (CIMName::equal(_properties[j].getName(),
281 superClassProperty.getName()))
|
282 karl 1.28 {
|
283 karl 1.29 pos = j;
284 break;
285 }
286 }
287 */
288 pos = findProperty(superClassProperty.getName());
289
290 // If property exists in super class but not in this one, then
291 // clone and insert it. Otherwise, the properties class
292 // origin was set above.
293
294 CIMProperty superproperty = superClassProperty.clone(true);
295
296 if (pos == PEG_NOT_FOUND)
297 {
298 superproperty.setPropagated(true);
299 _properties.insert(m++, superproperty);
300 }
301 else
302 {
303 // Property Qualifiers must propagate if allowed
304 karl 1.29 // If property exists in the superclass and in the subclass,
305 // then, enumerate the qualifiers of the superclass's property.
306 // If a qualifier is defined on the superclass's property
307 // but not on the subclass's, then add it to the subclass's
308 // property's qualifier list.
309 CIMProperty subproperty = _properties[pos];
310 for (Uint32 i = 0, n = superproperty.getQualifierCount();
311 i < n; i++)
312 {
313 Uint32 pos = PEG_NOT_FOUND;
314 CIMQualifier superClassQualifier =
315 superproperty.getQualifier(i);
316 const String name = superClassQualifier.getName();
317 /* ATTN KS This is replacement find function.
318 if((Uint32 j = subproperty.findQualifier(q.getName()) == PEG_NOT_FOUND)
|
319 karl 1.28 {
|
320 karl 1.29 subproperty.addQualifier(superClassQualifier);
321
|
322 karl 1.28 }
|
323 karl 1.29 */
324 for (Uint32 j = 0, m = subproperty.getQualifierCount();
325 j < m;
326 j++)
327 {
328 CIMConstQualifier q = subproperty.getQualifier(j);
329 if (CIMName::equal(name,
330 q.getName()))
331 {
332 pos = j;
333 break;
334 }
335 } // end comparison of subclass property's qualifiers
336 if (pos == PEG_NOT_FOUND)
337 {
338 subproperty.addQualifier(superClassQualifier);
339 }
340 /*
341 if ((pos = subproperty.findQualifier(name)) == PEG_NOT_FOUND)
342 {
343 subproperty.addQualifier(superClassQualifier);
344 karl 1.29 }
345 */
346 } // end iteration over superclass property's qualifiers
347 }
348 }
349
350 //----------------------------------------------------------------------
351 // Iterate all the methods of *this* class. Resolve each one and
352 // set the class-origin:
353 //----------------------------------------------------------------------
354
355 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
356 {
357 CIMMethod& method = _methods[i];
358 Uint32 pos = superClass.findMethod(method.getName());
359
360 if (pos == PEG_NOT_FOUND)
361 {
362 method.resolve(context, nameSpace);
363 }
364 else
365 karl 1.29 {
366 CIMConstMethod superClassMethod = superClass.getMethod(pos);
367 method.resolve(context, nameSpace, superClassMethod);
368 }
369 }
370
371 //----------------------------------------------------------------------
372 // Now prepend all methods inherited from the super-class (that
373 // are not overriden by this sub-class).
374 //----------------------------------------------------------------------
375
376 for (Uint32 i = 0, m = 0, n = superClass.getMethodCount(); i < n; i++)
377 {
378 CIMConstMethod superClassMethod = superClass.getMethod(i);
379
380 // Find the method in *this* class; if not found, then clone and
381 // insert it (setting the propagated flag). Otherwise, change
382 // the class-origin and propagated flag accordingly.
383
384 Uint32 pos = PEG_NOT_FOUND;
385 /********************** KS move to simpler version
386 karl 1.29 for (Uint32 j = m, n = _methods.size(); j < n; j++)
387 {
388 if (CIMName::equal(_methods[j].getName(),
389 superClassMethod.getName()))
|
390 karl 1.28 {
|
391 karl 1.29 pos = j;
392 break;
|
393 karl 1.28 }
|
394 karl 1.29 }
395
396 // If method exists in super class but not in this one, then
397 // clone and insert it. Otherwise, the method's class origin
398 // has already been set above.
399
400 if (pos == PEG_NOT_FOUND)
401 {
402 CIMMethod method = superClassMethod.clone();
403 method.setPropagated(true);
404 _methods.insert(m++, method);
405 }
406 */
407 if((pos = findMethod(superClassMethod.getName())) == PEG_NOT_FOUND)
|
408 karl 1.28 {
|
409 karl 1.29 CIMMethod method = superClassMethod.clone();
410 method.setPropagated(true);
411 _methods.insert(m++, method);
|
412 karl 1.28 }
413 }
|
414 karl 1.29
415 //----------------------------------------------------------------------
416 // Validate the qualifiers of this class:
417 //----------------------------------------------------------------------
418 //cout << "KSTEST Class Qualifiers resolve for class" << getClassName() << endl;
419 _qualifiers.resolve(
420 context,
421 nameSpace,
422 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
423 false,
424 superClass._rep->_qualifiers,
425 true);
|
426 mike 1.18 }
|
427 karl 1.29 else // No SuperClass exsts
|
428 mike 1.18 {
|
429 karl 1.28 //----------------------------------------------------------------------
430 // Resolve each property:
431 //----------------------------------------------------------------------
|
432 karl 1.29 //cout << "KSTEST Class Resolve, No Super class " << getClassName() << endl;
433
|
434 karl 1.28 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
435 _properties[i].resolve(context, nameSpace, false, true);
436
437 //----------------------------------------------------------------------
438 // Resolve each method:
439 //----------------------------------------------------------------------
440
441 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
442 _methods[i].resolve(context, nameSpace);
443
444 //----------------------------------------------------------------------
445 // Resolve the qualifiers:
446 //----------------------------------------------------------------------
447
448 CIMQualifierList dummy;
449
450 _qualifiers.resolve(
451 context,
452 nameSpace,
453 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
454 false,
455 karl 1.28 dummy,
456 true);
|
457 mike 1.18 }
458
459 // _resolved = true;
460 }
461
462 void CIMClassRep::toXml(Array<Sint8>& out) const
463 {
464 // Class opening element:
465
466 out << "<CLASS ";
|
467 chip 1.23 out << " NAME=\"" << _reference.getClassName() << "\" ";
|
468 mike 1.18
469 if (_superClassName.size())
470 out << " SUPERCLASS=\"" << _superClassName << "\" ";
471
472 out << ">\n";
473
474 // Qualifiers:
475
476 _qualifiers.toXml(out);
477
478 // Parameters:
479
480 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
481 _properties[i].toXml(out);
482
483 // Methods:
484
485 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
486 _methods[i].toXml(out);
487
488 // Class closing element:
489 mike 1.18
490 out << "</CLASS>\n";
491 }
|
492 mike 1.19 /** toMof prepares an 8-bit string with the MOF for the class.
493 The BNF for this is:
494 <pre>
495 classDeclaration = [ qualifierList ]
496 CLASS className [ alias ] [ superClass ]
497 "{" *classFeature "}" ";"
|
498 chip 1.21
|
499 mike 1.19 superClass = :" className
500
501 classFeature = propertyDeclaration | methodDeclaration
502
503 */
504
505 void CIMClassRep::toMof(Array<Sint8>& out) const
506 {
507 // Get and format the class qualifiers
|
508 chip 1.23 out << "\n// Class " << _reference.getClassName();
|
509 mike 1.19 if (_qualifiers.getCount())
510 out << "\n";
|
511 karl 1.26 out << "\n";
|
512 mike 1.19 _qualifiers.toMof(out);
513
514 // Separate qualifiers from Class Name
515 out << "\n";
516
517 // output class statement
|
518 chip 1.23 out << "class " << _reference.getClassName();
|
519 mike 1.19
520 if (_superClassName.size())
521 out << " : " << _superClassName;
|
522 chip 1.21
|
523 mike 1.19 out << "\n{";
524
525 // format the Properties:
526 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
527 {
528 // Generate MOF if this property not propogated
529 // Note that the test is required only because
530 // there is an error in getclass that does not
531 // test the localOnly flag.
532 if (!_properties[i].getPropagated())
533 _properties[i].toMof(out);
534 }
535
536 // Format the Methods: for non-propagated methods
537 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
538 {
539 if (!_methods[i].getPropagated())
540 _methods[i].toMof(out);
541 }
542
543 // Class closing element:
544 mike 1.19 out << "\n};\n";
545 }
|
546 mike 1.18
547 void CIMClassRep::print(PEGASUS_STD(ostream) &os) const
548 {
549 Array<Sint8> tmp;
550 toXml(tmp);
551 tmp.append('\0');
552 XmlWriter::indentedPrint(os, tmp.getData(), 4);
553 }
|
554 mike 1.19
555 void CIMClassRep::printMof(PEGASUS_STD(ostream) &os) const
556 {
557 Array<Sint8> tmp;
558 toMof(tmp);
559 tmp.append('\0');
560 os << tmp.getData() << PEGASUS_STD(endl);
561 }
562
|
563 mike 1.18
564 CIMClassRep::CIMClassRep()
565 {
566
567 }
568
569 CIMClassRep::CIMClassRep(const CIMClassRep& x) :
|
570 mike 1.20 CIMObjectRep(x),
571 _superClassName(x._superClassName)
|
572 mike 1.18 {
573 _methods.reserve(x._methods.size());
574
575 for (Uint32 i = 0, n = x._methods.size(); i < n; i++)
576 _methods.append(x._methods[i].clone());
577 }
578
|
579 kumpf 1.36 Boolean CIMClassRep::identical(const CIMObjectRep* x) const
|
580 mike 1.18 {
|
581 mike 1.20 if (!CIMObjectRep::identical(x))
|
582 mike 1.18 return false;
583
|
584 kumpf 1.36 const CIMClassRep* tmprep = dynamic_cast<const CIMClassRep*>(x);
585 if (!tmprep)
586 return false;
587
588 if (_superClassName != tmprep->_superClassName)
|
589 mike 1.18 return false;
590
|
591 mike 1.20 //
592 // Check methods:
593 //
|
594 mike 1.18
595 {
596 const Array<CIMMethod>& tmp1 = _methods;
|
597 kumpf 1.36 const Array<CIMMethod>& tmp2 = tmprep->_methods;
|
598 mike 1.18
599 if (tmp1.size() != tmp2.size())
600 return false;
601
602 for (Uint32 i = 0, n = tmp1.size(); i < n; i++)
603 {
604 if (!tmp1[i].identical(tmp2[i]))
605 return false;
606
607 if (tmp1[i].getClassOrigin() != tmp2[i].getClassOrigin())
608 return false;
609
610 if (tmp1[i].getPropagated() != tmp2[i].getPropagated())
611 return false;
612 }
613 }
614
|
615 kumpf 1.36 if (_resolved != tmprep->_resolved)
|
616 mike 1.18 return false;
617
618 return true;
619 }
620
621 void CIMClassRep::getKeyNames(Array<String>& keyNames) const
622 {
623 keyNames.clear();
624
625 for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)
626 {
627 CIMConstProperty property = getProperty(i);
628
629 if (property.isKey())
630 keyNames.append(property.getName());
631 }
632 }
633
634 Boolean CIMClassRep::hasKeys() const
635 {
636 for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)
637 mike 1.18 {
638 CIMConstProperty property = getProperty(i);
639
640 if (getProperty(i).isKey())
641 return true;
642 }
643
644 return false;
645 }
646
647 PEGASUS_NAMESPACE_END
648
|