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