1 mike 1.18 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.44 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.18 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 chip 1.21 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.18 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
|
12 kumpf 1.44 //
|
13 chip 1.21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.18 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 chip 1.21 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
|
26 kumpf 1.35 // Modified By: Karl Schopmeyer(k.schopmeyer@attglobal.net)
27 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
28 kumpf 1.46 // Carol Ann Krug Graves, Hewlett-Packard Company
29 // (carolann_graves@hp.com)
|
30 mike 1.18 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
|
33 kumpf 1.34 #include "CIMClassRep.h"
|
34 mike 1.18 #include "DeclContext.h"
35 #include "Indentor.h"
36 #include "CIMName.h"
37 #include "CIMQualifierNames.h"
|
38 kumpf 1.37 #include "CIMScope.h"
|
39 mike 1.18 #include "XmlWriter.h"
|
40 kumpf 1.42 #include "MofWriter.h"
|
41 karl 1.30 #include <Pegasus/Common/Tracer.h>
|
42 mike 1.18
43 PEGASUS_NAMESPACE_BEGIN
|
44 karl 1.29 PEGASUS_USING_STD;
|
45 mike 1.18
46 CIMClassRep::CIMClassRep(
|
47 kumpf 1.43 const CIMObjectPath& reference,
|
48 chip 1.21 const String& superClassName)
|
49 mike 1.20 :
|
50 chip 1.23 CIMObjectRep(reference),
|
51 mike 1.20 _superClassName(superClassName)
|
52 mike 1.18 {
53 if (superClassName.size() && !CIMName::legal(superClassName))
54 throw IllegalName();
55 }
56
57 CIMClassRep::~CIMClassRep()
58 {
59
60 }
61
62 Boolean CIMClassRep::isAssociation() const
63 {
64 Uint32 pos = findQualifier(CIMQualifierNames::ASSOCIATION);
65
66 if (pos == PEG_NOT_FOUND)
67 return false;
68
69 Boolean flag;
70
71 const CIMValue& value = getQualifier(pos).getValue();
72
73 mike 1.18 if (value.getType() != CIMType::BOOLEAN)
74 return false;
75
76 value.get(flag);
77 return flag;
78 }
79
80 Boolean CIMClassRep::isAbstract() const
81 {
82 Uint32 pos = findQualifier(CIMQualifierNames::ABSTRACT);
83
84 if (pos == PEG_NOT_FOUND)
85 return false;
86
87 Boolean flag;
88 const CIMValue& value = getQualifier(pos).getValue();
89
90 if (value.getType() != CIMType::BOOLEAN)
91 return false;
92
93 value.get(flag);
94 mike 1.18 return flag;
95 }
96
|
97 karl 1.30 Boolean CIMClassRep::isTrueQualifier(const String& name) const
98 {
99 Uint32 pos = findQualifier(name);
100
101 if (pos == PEG_NOT_FOUND)
102 return false;
103
104 Boolean flag;
105 const CIMValue& value = getQualifier(pos).getValue();
106
107 if (value.getType() != CIMType::BOOLEAN)
108 return false;
109
110 value.get(flag);
111 return flag;
112 }
113
|
114 mike 1.18 void CIMClassRep::setSuperClassName(const String& superClassName)
115 {
116 if (!CIMName::legal(superClassName))
117 throw IllegalName();
118
119 _superClassName = superClassName;
120 }
121
122 void CIMClassRep::addProperty(const CIMProperty& x)
123 {
|
124 kumpf 1.39 if (x.isNull())
|
125 kumpf 1.38 throw UninitializedHandle();
|
126 mike 1.18
127 // Reject addition of duplicate property name:
128
129 if (findProperty(x.getName()) != PEG_NOT_FOUND)
130 throw AlreadyExists();
131
132 // Reject addition of references to non-associations:
133
134 if (!isAssociation() && x.getValue().getType() == CIMType::REFERENCE)
|
135 chip 1.23 throw AddedReferenceToClass(_reference.getClassName());
|
136 mike 1.18
137 // Set the class origin:
138 // ATTN: put this check in other places:
139
140 if (x.getClassOrigin().size() == 0)
|
141 chip 1.23 CIMProperty(x).setClassOrigin(_reference.getClassName());
|
142 mike 1.18
143 // Add the property:
144
145 _properties.append(x);
146 }
147
148 void CIMClassRep::addMethod(const CIMMethod& x)
149 {
|
150 kumpf 1.39 if (x.isNull())
|
151 kumpf 1.38 throw UninitializedHandle();
|
152 mike 1.18
153 // Reject duplicate method names:
154
155 if (findMethod(x.getName()) != PEG_NOT_FOUND)
156 throw AlreadyExists();
157
158 // Add the method:
159
160 _methods.append(x);
161 }
162
|
163 kumpf 1.33 Uint32 CIMClassRep::findMethod(const String& name) const
|
164 mike 1.18 {
165 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
166 {
167 if (CIMName::equal(_methods[i].getName(), name))
168 return i;
169 }
170
171 return PEG_NOT_FOUND;
172 }
|
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 kumpf 1.39 if (superClass.isNull())
|
223 karl 1.29 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 kumpf 1.41 XmlWriter::appendPropertyElement(out, _properties[i]);
|
482 mike 1.18
483 // Methods:
484
485 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
|
486 kumpf 1.41 XmlWriter::appendMethodElement(out, _methods[i]);
|
487 mike 1.18
488 // Class closing element:
489
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 kumpf 1.42 MofWriter::appendPropertyElement(out, _properties[i]);
|
534 mike 1.19 }
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 kumpf 1.42 MofWriter::appendMethodElement(out, _methods[i]);
|
541 mike 1.19 }
542
543 // Class closing element:
544 out << "\n};\n";
545 }
546
|
547 mike 1.18
548 CIMClassRep::CIMClassRep()
549 {
550 }
551
552 CIMClassRep::CIMClassRep(const CIMClassRep& x) :
|
553 mike 1.20 CIMObjectRep(x),
554 _superClassName(x._superClassName)
|
555 mike 1.18 {
|
556 kumpf 1.45 _methods.reserveCapacity(x._methods.size());
|
557 mike 1.18
558 for (Uint32 i = 0, n = x._methods.size(); i < n; i++)
559 _methods.append(x._methods[i].clone());
560 }
561
|
562 kumpf 1.36 Boolean CIMClassRep::identical(const CIMObjectRep* x) const
|
563 mike 1.18 {
|
564 mike 1.20 if (!CIMObjectRep::identical(x))
|
565 mike 1.18 return false;
566
|
567 kumpf 1.36 const CIMClassRep* tmprep = dynamic_cast<const CIMClassRep*>(x);
568 if (!tmprep)
569 return false;
570
571 if (_superClassName != tmprep->_superClassName)
|
572 mike 1.18 return false;
573
|
574 mike 1.20 //
575 // Check methods:
576 //
|
577 mike 1.18
578 {
579 const Array<CIMMethod>& tmp1 = _methods;
|
580 kumpf 1.36 const Array<CIMMethod>& tmp2 = tmprep->_methods;
|
581 mike 1.18
582 if (tmp1.size() != tmp2.size())
583 return false;
584
585 for (Uint32 i = 0, n = tmp1.size(); i < n; i++)
586 {
587 if (!tmp1[i].identical(tmp2[i]))
588 return false;
589
590 if (tmp1[i].getClassOrigin() != tmp2[i].getClassOrigin())
591 return false;
592
593 if (tmp1[i].getPropagated() != tmp2[i].getPropagated())
594 return false;
595 }
596 }
597
|
598 kumpf 1.36 if (_resolved != tmprep->_resolved)
|
599 mike 1.18 return false;
600
601 return true;
602 }
603
604 void CIMClassRep::getKeyNames(Array<String>& keyNames) const
605 {
606 keyNames.clear();
607
608 for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)
609 {
610 CIMConstProperty property = getProperty(i);
611
612 if (property.isKey())
613 keyNames.append(property.getName());
614 }
615 }
616
617 Boolean CIMClassRep::hasKeys() const
618 {
619 for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)
620 mike 1.18 {
621 CIMConstProperty property = getProperty(i);
622
623 if (getProperty(i).isKey())
624 return true;
625 }
626
627 return false;
628 }
629
630 PEGASUS_NAMESPACE_END
631
|