Added headers
[tpot/pegasus/.git] / src / Pegasus / Common / CIMClassRep.cpp
1 //%/////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM\r
4 //\r
5 // Permission is hereby granted, free of charge, to any person obtaining a copy\r
6 // of this software and associated documentation files (the "Software"), to \r
7 // deal in the Software without restriction, including without limitation the \r
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or \r
9 // sell copies of the Software, and to permit persons to whom the Software is\r
10 // furnished to do so, subject to the following conditions:\r
11 // \r
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN \r
13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED\r
14 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\r
15 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR \r
16 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT \r
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN \r
18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
20 //\r
21 //==============================================================================\r
22 //\r
23 // Author: Mike Brasher (mbrasher@bmc.com)\r
24 //\r
25 // Modified By:\r
26 //\r
27 //%/////////////////////////////////////////////////////////////////////////////\r
28 \r
29 #include "CIMClass.h"\r
30 #include "DeclContext.h"\r
31 #include "Indentor.h"\r
32 #include "CIMName.h"\r
33 #include "CIMQualifierNames.h"\r
34 #include "XmlWriter.h"\r
35 \r
36 PEGASUS_NAMESPACE_BEGIN\r
37 \r
38 CIMClassRep::CIMClassRep(\r
39     const String& className,\r
40     const String& superClassName)\r
41     : _className(className), _superClassName(superClassName), _resolved(false)\r
42 {\r
43     if (!CIMName::legal(className))\r
44         throw IllegalName();\r
45 \r
46     if (superClassName.size() && !CIMName::legal(superClassName))\r
47         throw IllegalName();\r
48 }\r
49 \r
50 CIMClassRep::~CIMClassRep()\r
51 {\r
52 \r
53 }\r
54 \r
55 Boolean CIMClassRep::isAssociation() const\r
56 {\r
57     Uint32 pos = findQualifier(CIMQualifierNames::ASSOCIATION);\r
58 \r
59     if (pos == PEG_NOT_FOUND)\r
60         return false;\r
61 \r
62     Boolean flag;\r
63 \r
64     const CIMValue& value = getQualifier(pos).getValue();\r
65 \r
66     if (value.getType() != CIMType::BOOLEAN)\r
67         return false;\r
68 \r
69     value.get(flag);\r
70     return flag;\r
71 }\r
72 \r
73 Boolean CIMClassRep::isAbstract() const\r
74 {\r
75     Uint32 pos = findQualifier(CIMQualifierNames::ABSTRACT);\r
76 \r
77     if (pos == PEG_NOT_FOUND)\r
78         return false;\r
79 \r
80     Boolean flag;\r
81     const CIMValue& value = getQualifier(pos).getValue();\r
82 \r
83     if (value.getType() != CIMType::BOOLEAN)\r
84         return false;\r
85 \r
86     value.get(flag);\r
87     return flag;\r
88 }\r
89 \r
90 void CIMClassRep::setSuperClassName(const String& superClassName)\r
91 {\r
92     if (!CIMName::legal(superClassName))\r
93         throw IllegalName();\r
94 \r
95     _superClassName = superClassName;\r
96 }\r
97 \r
98 void CIMClassRep::addProperty(const CIMProperty& x)\r
99 {\r
100     if (!x)\r
101         throw UnitializedHandle();\r
102 \r
103     // Reject addition of duplicate property name:\r
104 \r
105     if (findProperty(x.getName()) != PEG_NOT_FOUND)\r
106         throw AlreadyExists();\r
107 \r
108     // Reject addition of references to non-associations:\r
109 \r
110     if (!isAssociation() && x.getValue().getType() == CIMType::REFERENCE)\r
111         throw AddedReferenceToClass(_className);\r
112 \r
113     // Set the class origin:\r
114     // ATTN: put this check in other places:\r
115 \r
116     if (x.getClassOrigin().size() == 0)\r
117         CIMProperty(x).setClassOrigin(_className);\r
118 \r
119     // Add the property:\r
120 \r
121     _properties.append(x);\r
122 }\r
123 \r
124 \r
125 Uint32 CIMClassRep::findProperty(const String& name)\r
126 {\r
127     for (Uint32 i = 0, n = _properties.size(); i < n; i++)\r
128     {\r
129         if (CIMName::equal(_properties[i].getName(), name))\r
130             return i;\r
131     }\r
132 \r
133     return PEG_NOT_FOUND;\r
134 }\r
135 \r
136 Boolean CIMClassRep::existsProperty(const String& name)\r
137 {\r
138     return (findProperty(name) != PEG_NOT_FOUND) ?\r
139                     true : false;\r
140 }\r
141 \r
142 CIMProperty CIMClassRep::getProperty(Uint32 pos)\r
143 {\r
144     if (pos >= _properties.size())\r
145         throw OutOfBounds();\r
146 \r
147     return _properties[pos];\r
148 }\r
149 \r
150 void CIMClassRep::removeProperty(Uint32 pos)\r
151 {\r
152     if (pos >= _properties.size())\r
153         throw OutOfBounds();\r
154 \r
155     _properties.remove(pos);\r
156 }\r
157 \r
158 \r
159 Uint32 CIMClassRep::getPropertyCount() const\r
160 {\r
161     return _properties.size();\r
162 }\r
163 \r
164 void CIMClassRep::addMethod(const CIMMethod& x)\r
165 {\r
166     if (!x)\r
167         throw UnitializedHandle();\r
168 \r
169     // Reject duplicate method names:\r
170 \r
171     if (findMethod(x.getName()) != PEG_NOT_FOUND)\r
172         throw AlreadyExists();\r
173 \r
174     // Add the method:\r
175 \r
176     _methods.append(x);\r
177 }\r
178 \r
179 Uint32 CIMClassRep::findMethod(const String& name)\r
180 {\r
181     for (Uint32 i = 0, n = _methods.size(); i < n; i++)\r
182     {\r
183         if (CIMName::equal(_methods[i].getName(), name))\r
184             return i;\r
185     }\r
186 \r
187     return PEG_NOT_FOUND;\r
188 }\r
189 \r
190 Boolean CIMClassRep::existsMethod(const String& name)\r
191 {\r
192     return(findMethod(name) != PEG_NOT_FOUND) ?\r
193                         true : false;\r
194 }\r
195 CIMMethod CIMClassRep::getMethod(Uint32 pos)\r
196 {\r
197     if (pos >= _methods.size())\r
198         throw OutOfBounds();\r
199 \r
200     return _methods[pos];\r
201 }\r
202 \r
203 Uint32 CIMClassRep::getMethodCount() const\r
204 {\r
205     return _methods.size();\r
206 }\r
207 //ATTN: Ks 18 May\r
208 void CIMClassRep::removeMethod(Uint32 pos)\r
209 {\r
210     if (pos >= _methods.size())\r
211         throw OutOfBounds();\r
212 \r
213     _methods.remove(pos);\r
214 }\r
215 \r
216 void CIMClassRep::resolve(\r
217     DeclContext* context,\r
218     const String& nameSpace)\r
219 {\r
220 #if 0\r
221     if (_resolved)\r
222         throw ClassAlreadyResolved(_className);\r
223 #endif\r
224 \r
225     if (!context)\r
226         throw NullPointer();\r
227 \r
228     if (_superClassName.size())\r
229     {\r
230         //----------------------------------------------------------------------\r
231         // First check to see if the super-class really exists:\r
232         //----------------------------------------------------------------------\r
233 \r
234         CIMConstClass superClass\r
235             = context->lookupClass(nameSpace, _superClassName);\r
236 \r
237         if (!superClass)\r
238             throw PEGASUS_CIM_EXCEPTION(INVALID_SUPERCLASS, _superClassName);\r
239 \r
240 #if 0\r
241         if (!superClass._rep->_resolved)\r
242             throw ClassNotResolved(_superClassName);\r
243 #endif\r
244 \r
245         //----------------------------------------------------------------------\r
246         // Iterate all the properties of *this* class. Resolve each one and\r
247         // set the class-origin:\r
248         //----------------------------------------------------------------------\r
249 \r
250         for (Uint32 i = 0, n = _properties.size(); i < n; i++)\r
251         {\r
252             CIMProperty& property = _properties[i];\r
253             Uint32 pos = superClass.findProperty(property.getName());\r
254 \r
255             if (pos == PEG_NOT_FOUND)\r
256             {\r
257                 property.resolve(context, nameSpace, false);\r
258             }\r
259             else\r
260             {\r
261                 CIMConstProperty superClassProperty =\r
262                 superClass.getProperty(pos);\r
263                 property.resolve(context, nameSpace, false, superClassProperty);\r
264             }\r
265         }\r
266 \r
267         //----------------------------------------------------------------------\r
268         // Now prepend all properties inherited from the super-class (that\r
269         // are not overriden by this sub-class).\r
270         //----------------------------------------------------------------------\r
271 \r
272         // Iterate super-class properties:\r
273 \r
274         for (Uint32 i = 0, m = 0, n = superClass.getPropertyCount(); i < n; i++)\r
275         {\r
276             CIMConstProperty superClassProperty = superClass.getProperty(i);\r
277 \r
278             // Find the property in *this* class; if not found, then clone and\r
279             // insert it (setting the propagated flag). Otherwise, change\r
280             // the class-origin and propagated flag accordingly.\r
281 \r
282             Uint32 pos = PEG_NOT_FOUND;\r
283 \r
284             for (Uint32 j = m, n = _properties.size(); j < n; j++)\r
285             {\r
286                 if (CIMName::equal(\r
287                     _properties[j].getName(),\r
288                     superClassProperty.getName()))\r
289                 {\r
290                     pos = j;\r
291                     break;\r
292                 }\r
293             }\r
294 \r
295             // If property exists in super class but not in this one, then\r
296             // clone and insert it. Otherwise, the properties class\r
297             // origin was set above.\r
298 \r
299             if (pos == PEG_NOT_FOUND)\r
300             {\r
301                 CIMProperty property = superClassProperty.clone();\r
302                 property.setPropagated(true);\r
303                 _properties.insert(m++, property);\r
304             }\r
305         }\r
306 \r
307         //----------------------------------------------------------------------\r
308         // Iterate all the methods of *this* class. Resolve each one and\r
309         // set the class-origin:\r
310         //----------------------------------------------------------------------\r
311 \r
312         for (Uint32 i = 0, n = _methods.size(); i < n; i++)\r
313         {\r
314             CIMMethod& method = _methods[i];\r
315             Uint32 pos = superClass.findMethod(method.getName());\r
316 \r
317             if (pos == PEG_NOT_FOUND)\r
318             {\r
319                 method.resolve(context, nameSpace);\r
320             }\r
321             else\r
322             {\r
323                 CIMConstMethod superClassMethod = superClass.getMethod(pos);\r
324                 method.resolve(context, nameSpace, superClassMethod);\r
325             }\r
326         }\r
327 \r
328         //----------------------------------------------------------------------\r
329         // Now prepend all methods inherited from the super-class (that\r
330         // are not overriden by this sub-class).\r
331         //----------------------------------------------------------------------\r
332 \r
333         for (Uint32 i = 0, m = 0, n = superClass.getMethodCount(); i < n; i++)\r
334         {\r
335             CIMConstMethod superClassMethod = superClass.getMethod(i);\r
336 \r
337             // Find the method in *this* class; if not found, then clone and\r
338             // insert it (setting the propagated flag). Otherwise, change\r
339             // the class-origin and propagated flag accordingly.\r
340 \r
341             Uint32 pos = PEG_NOT_FOUND;\r
342 \r
343             for (Uint32 j = m, n = _methods.size(); j < n; j++)\r
344             {\r
345                 if (CIMName::equal(\r
346                     _methods[j].getName(),\r
347                     superClassMethod.getName()))\r
348                 {\r
349                     pos = j;\r
350                     break;\r
351                 }\r
352             }\r
353 \r
354             // If method exists in super class but not in this one, then\r
355             // clone and insert it. Otherwise, the method's class origin\r
356             // has already been set above.\r
357 \r
358             if (pos == PEG_NOT_FOUND)\r
359             {\r
360                 CIMMethod method = superClassMethod.clone();\r
361                 method.setPropagated(true);\r
362                 _methods.insert(m++, method);\r
363             }\r
364         }\r
365 \r
366         //----------------------------------------------------------------------\r
367         // Validate the qualifiers of this class:\r
368         //----------------------------------------------------------------------\r
369 \r
370         _qualifiers.resolve(\r
371             context,\r
372             nameSpace,\r
373             isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,\r
374             false,\r
375             superClass._rep->_qualifiers);\r
376     }\r
377     else\r
378     {\r
379         //----------------------------------------------------------------------\r
380         // Resolve each property:\r
381         //----------------------------------------------------------------------\r
382 \r
383         for (Uint32 i = 0, n = _properties.size(); i < n; i++)\r
384             _properties[i].resolve(context, nameSpace, false);\r
385 \r
386         //----------------------------------------------------------------------\r
387         // Resolve each method:\r
388         //----------------------------------------------------------------------\r
389 \r
390         for (Uint32 i = 0, n = _methods.size(); i < n; i++)\r
391             _methods[i].resolve(context, nameSpace);\r
392 \r
393         //----------------------------------------------------------------------\r
394         // Resolve the qualifiers:\r
395         //----------------------------------------------------------------------\r
396 \r
397         CIMQualifierList dummy;\r
398 \r
399         _qualifiers.resolve(\r
400             context,\r
401             nameSpace,\r
402             isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,\r
403             false,\r
404             dummy);\r
405     }\r
406 \r
407     // _resolved = true;\r
408 }\r
409 \r
410 void CIMClassRep::toXml(Array<Sint8>& out) const\r
411 {\r
412     // Class opening element:\r
413 \r
414     out << "<CLASS ";\r
415     out << " NAME=\"" << _className << "\" ";\r
416 \r
417     if (_superClassName.size())\r
418         out << " SUPERCLASS=\"" << _superClassName << "\" ";\r
419 \r
420     out << ">\n";\r
421 \r
422     // Qualifiers:\r
423 \r
424     _qualifiers.toXml(out);\r
425 \r
426     // Parameters:\r
427 \r
428     for (Uint32 i = 0, n = _properties.size(); i < n; i++)\r
429         _properties[i].toXml(out);\r
430 \r
431     // Methods:\r
432 \r
433     for (Uint32 i = 0, n = _methods.size(); i < n; i++)\r
434         _methods[i].toXml(out);\r
435 \r
436     // Class closing element:\r
437 \r
438     out << "</CLASS>\n";\r
439 }\r
440 \r
441 void CIMClassRep::print(PEGASUS_STD(ostream) &os) const\r
442 {\r
443     Array<Sint8> tmp;\r
444     toXml(tmp);\r
445     tmp.append('\0');\r
446     XmlWriter::indentedPrint(os, tmp.getData(), 4);\r
447     // cout << tmp.getData() << endl;\r
448 }\r
449 \r
450 CIMClassRep::CIMClassRep()\r
451 {\r
452 \r
453 }\r
454 \r
455 CIMClassRep::CIMClassRep(const CIMClassRep& x) :\r
456     Sharable(),\r
457     _className(x._className),\r
458     _superClassName(x._superClassName),\r
459     _resolved(x._resolved)\r
460 {\r
461     x._qualifiers.cloneTo(_qualifiers);\r
462 \r
463     _properties.reserve(x._properties.size());\r
464 \r
465     for (Uint32 i = 0, n = x._properties.size(); i < n; i++)\r
466         _properties.append(x._properties[i].clone());\r
467 \r
468     _methods.reserve(x._methods.size());\r
469 \r
470     for (Uint32 i = 0, n = x._methods.size(); i < n; i++)\r
471         _methods.append(x._methods[i].clone());\r
472 }\r
473 \r
474 CIMClassRep& CIMClassRep::operator=(const CIMClassRep& x)\r
475 {\r
476     return *this;\r
477 }\r
478 \r
479 Boolean CIMClassRep::identical(const CIMClassRep* x) const\r
480 {\r
481     if (_className != x->_className)\r
482         return false;\r
483 \r
484     if (_superClassName != x->_superClassName)\r
485         return false;\r
486 \r
487     if (!_qualifiers.identical(x->_qualifiers))\r
488         return false;\r
489 \r
490     // Compare properties:\r
491 \r
492     {\r
493         const Array<CIMProperty>& tmp1 = _properties;\r
494         const Array<CIMProperty>& tmp2 = x->_properties;\r
495 \r
496         if (tmp1.size() != tmp2.size())\r
497             return false;\r
498 \r
499         for (Uint32 i = 0, n = tmp1.size(); i < n; i++)\r
500         {\r
501             if (!tmp1[i].identical(tmp2[i]))\r
502                 return false;\r
503         }\r
504     }\r
505 \r
506     // Compare methods:\r
507 \r
508     {\r
509         const Array<CIMMethod>& tmp1 = _methods;\r
510         const Array<CIMMethod>& tmp2 = x->_methods;\r
511 \r
512         if (tmp1.size() != tmp2.size())\r
513             return false;\r
514 \r
515         for (Uint32 i = 0, n = tmp1.size(); i < n; i++)\r
516         {\r
517             if (!tmp1[i].identical(tmp2[i]))\r
518                 return false;\r
519 \r
520             if (tmp1[i].getClassOrigin() != tmp2[i].getClassOrigin())\r
521                 return false;\r
522 \r
523             if (tmp1[i].getPropagated() != tmp2[i].getPropagated())\r
524                 return false;\r
525         }\r
526     }\r
527 \r
528     if (_resolved != x->_resolved)\r
529         return false;\r
530 \r
531     return true;\r
532 }\r
533 \r
534 void CIMClassRep::getKeyNames(Array<String>& keyNames) const\r
535 {\r
536     keyNames.clear();\r
537 \r
538     for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)\r
539     {\r
540         CIMConstProperty property = getProperty(i);\r
541 \r
542         if (property.isKey())\r
543             keyNames.append(property.getName());\r
544     }\r
545 }\r
546 \r
547 PEGASUS_NAMESPACE_END\r
548 \r