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