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 // 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 // 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 //
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
13 // 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 // 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 // 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 mike 1.18 //
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 const String& className,
40 const String& superClassName)
41 : _className(className), _superClassName(superClassName), _resolved(false)
42 {
43 mike 1.18 if (!CIMName::legal(className))
44 throw IllegalName();
45
46 if (superClassName.size() && !CIMName::legal(superClassName))
47 throw IllegalName();
48 }
49
50 CIMClassRep::~CIMClassRep()
51 {
52
53 }
54
55 Boolean CIMClassRep::isAssociation() const
56 {
57 Uint32 pos = findQualifier(CIMQualifierNames::ASSOCIATION);
58
59 if (pos == PEG_NOT_FOUND)
60 return false;
61
62 Boolean flag;
63
64 mike 1.18 const CIMValue& value = getQualifier(pos).getValue();
65
66 if (value.getType() != CIMType::BOOLEAN)
67 return false;
68
69 value.get(flag);
70 return flag;
71 }
72
73 Boolean CIMClassRep::isAbstract() const
74 {
75 Uint32 pos = findQualifier(CIMQualifierNames::ABSTRACT);
76
77 if (pos == PEG_NOT_FOUND)
78 return false;
79
80 Boolean flag;
81 const CIMValue& value = getQualifier(pos).getValue();
82
83 if (value.getType() != CIMType::BOOLEAN)
84 return false;
85 mike 1.18
86 value.get(flag);
87 return flag;
88 }
89
90 void CIMClassRep::setSuperClassName(const String& superClassName)
91 {
92 if (!CIMName::legal(superClassName))
93 throw IllegalName();
94
95 _superClassName = superClassName;
96 }
97
98 void CIMClassRep::addProperty(const CIMProperty& x)
99 {
100 if (!x)
101 throw UnitializedHandle();
102
103 // Reject addition of duplicate property name:
104
105 if (findProperty(x.getName()) != PEG_NOT_FOUND)
106 mike 1.18 throw AlreadyExists();
107
108 // Reject addition of references to non-associations:
109
110 if (!isAssociation() && x.getValue().getType() == CIMType::REFERENCE)
111 throw AddedReferenceToClass(_className);
112
113 // Set the class origin:
114 // ATTN: put this check in other places:
115
116 if (x.getClassOrigin().size() == 0)
117 CIMProperty(x).setClassOrigin(_className);
118
119 // Add the property:
120
121 _properties.append(x);
122 }
123
124
125 Uint32 CIMClassRep::findProperty(const String& name)
126 {
127 mike 1.18 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
128 {
129 if (CIMName::equal(_properties[i].getName(), name))
130 return i;
131 }
132
133 return PEG_NOT_FOUND;
134 }
135
136 Boolean CIMClassRep::existsProperty(const String& name)
137 {
138 return (findProperty(name) != PEG_NOT_FOUND) ?
139 true : false;
140 }
141
142 CIMProperty CIMClassRep::getProperty(Uint32 pos)
143 {
144 if (pos >= _properties.size())
145 throw OutOfBounds();
146
147 return _properties[pos];
148 mike 1.18 }
149
150 void CIMClassRep::removeProperty(Uint32 pos)
151 {
152 if (pos >= _properties.size())
153 throw OutOfBounds();
154
155 _properties.remove(pos);
156 }
157
158
159 Uint32 CIMClassRep::getPropertyCount() const
160 {
161 return _properties.size();
162 }
163
164 void CIMClassRep::addMethod(const CIMMethod& x)
165 {
166 if (!x)
167 throw UnitializedHandle();
168
169 mike 1.18 // Reject duplicate method names:
170
171 if (findMethod(x.getName()) != PEG_NOT_FOUND)
172 throw AlreadyExists();
173
174 // Add the method:
175
176 _methods.append(x);
177 }
178
179 Uint32 CIMClassRep::findMethod(const String& name)
180 {
181 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
182 {
183 if (CIMName::equal(_methods[i].getName(), name))
184 return i;
185 }
186
187 return PEG_NOT_FOUND;
188 }
189
190 mike 1.18 Boolean CIMClassRep::existsMethod(const String& name)
191 {
192 return(findMethod(name) != PEG_NOT_FOUND) ?
193 true : false;
194 }
195 CIMMethod CIMClassRep::getMethod(Uint32 pos)
196 {
197 if (pos >= _methods.size())
198 throw OutOfBounds();
199
200 return _methods[pos];
201 }
202
203 Uint32 CIMClassRep::getMethodCount() const
204 {
205 return _methods.size();
206 }
207 //ATTN: Ks 18 May
208 void CIMClassRep::removeMethod(Uint32 pos)
209 {
210 if (pos >= _methods.size())
211 mike 1.18 throw OutOfBounds();
212
213 _methods.remove(pos);
214 }
215
216 void CIMClassRep::resolve(
217 DeclContext* context,
218 const String& nameSpace)
219 {
220 #if 0
221 if (_resolved)
222 throw ClassAlreadyResolved(_className);
223 #endif
224
225 if (!context)
226 throw NullPointer();
227
228 if (_superClassName.size())
229 {
230 //----------------------------------------------------------------------
231 // First check to see if the super-class really exists:
232 mike 1.18 //----------------------------------------------------------------------
233
234 CIMConstClass superClass
235 = context->lookupClass(nameSpace, _superClassName);
236
237 if (!superClass)
238 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_SUPERCLASS,_superClassName);
239
240 #if 0
241 if (!superClass._rep->_resolved)
242 throw ClassNotResolved(_superClassName);
243 #endif
244
245 //----------------------------------------------------------------------
246 // Iterate all the properties of *this* class. Resolve each one and
247 // set the class-origin:
248 //----------------------------------------------------------------------
249
250 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
251 {
252 CIMProperty& property = _properties[i];
253 mike 1.18 Uint32 pos = superClass.findProperty(property.getName());
254
255 if (pos == PEG_NOT_FOUND)
256 {
257 property.resolve(context, nameSpace, false);
258 }
259 else
260 {
261 CIMConstProperty superClassProperty =
262 superClass.getProperty(pos);
263 property.resolve(context, nameSpace, false, superClassProperty);
264 }
265 }
266
267 //----------------------------------------------------------------------
268 // Now prepend all properties inherited from the super-class (that
269 // are not overriden by this sub-class).
270 //----------------------------------------------------------------------
271
272 // Iterate super-class properties:
273
274 mike 1.18 for (Uint32 i = 0, m = 0, n = superClass.getPropertyCount(); i < n; i++)
275 {
276 CIMConstProperty superClassProperty = superClass.getProperty(i);
277
278 // Find the property in *this* class; if not found, then clone and
279 // insert it (setting the propagated flag). Otherwise, change
280 // the class-origin and propagated flag accordingly.
281
282 Uint32 pos = PEG_NOT_FOUND;
283
284 for (Uint32 j = m, n = _properties.size(); j < n; j++)
285 {
286 if (CIMName::equal(
287 _properties[j].getName(),
288 superClassProperty.getName()))
289 {
290 pos = j;
291 break;
292 }
293 }
294
295 mike 1.18 // If property exists in super class but not in this one, then
296 // clone and insert it. Otherwise, the properties class
297 // origin was set above.
298
299 if (pos == PEG_NOT_FOUND)
300 {
301 CIMProperty property = superClassProperty.clone();
302 property.setPropagated(true);
303 _properties.insert(m++, property);
304 }
305 }
306
307 //----------------------------------------------------------------------
308 // Iterate all the methods of *this* class. Resolve each one and
309 // set the class-origin:
310 //----------------------------------------------------------------------
311
312 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
313 {
314 CIMMethod& method = _methods[i];
315 Uint32 pos = superClass.findMethod(method.getName());
316 mike 1.18
317 if (pos == PEG_NOT_FOUND)
318 {
319 method.resolve(context, nameSpace);
320 }
321 else
322 {
323 CIMConstMethod superClassMethod = superClass.getMethod(pos);
324 method.resolve(context, nameSpace, superClassMethod);
325 }
326 }
327
328 //----------------------------------------------------------------------
329 // Now prepend all methods inherited from the super-class (that
330 // are not overriden by this sub-class).
331 //----------------------------------------------------------------------
332
333 for (Uint32 i = 0, m = 0, n = superClass.getMethodCount(); i < n; i++)
334 {
335 CIMConstMethod superClassMethod = superClass.getMethod(i);
336
337 mike 1.18 // Find the method in *this* class; if not found, then clone and
338 // insert it (setting the propagated flag). Otherwise, change
339 // the class-origin and propagated flag accordingly.
340
341 Uint32 pos = PEG_NOT_FOUND;
342
343 for (Uint32 j = m, n = _methods.size(); j < n; j++)
344 {
345 if (CIMName::equal(
346 _methods[j].getName(),
347 superClassMethod.getName()))
348 {
349 pos = j;
350 break;
351 }
352 }
353
354 // If method exists in super class but not in this one, then
355 // clone and insert it. Otherwise, the method's class origin
356 // has already been set above.
357
358 mike 1.18 if (pos == PEG_NOT_FOUND)
359 {
360 CIMMethod method = superClassMethod.clone();
361 method.setPropagated(true);
362 _methods.insert(m++, method);
363 }
364 }
365
366 //----------------------------------------------------------------------
367 // Validate the qualifiers of this class:
368 //----------------------------------------------------------------------
369
370 _qualifiers.resolve(
371 context,
372 nameSpace,
373 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
374 false,
375 superClass._rep->_qualifiers);
376 }
377 else
378 {
379 mike 1.18 //----------------------------------------------------------------------
380 // Resolve each property:
381 //----------------------------------------------------------------------
382
383 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
384 _properties[i].resolve(context, nameSpace, false);
385
386 //----------------------------------------------------------------------
387 // Resolve each method:
388 //----------------------------------------------------------------------
389
390 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
391 _methods[i].resolve(context, nameSpace);
392
393 //----------------------------------------------------------------------
394 // Resolve the qualifiers:
395 //----------------------------------------------------------------------
396
397 CIMQualifierList dummy;
398
399 _qualifiers.resolve(
400 mike 1.18 context,
401 nameSpace,
402 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
403 false,
404 dummy);
405 }
406
407 // _resolved = true;
408 }
409
410 void CIMClassRep::toXml(Array<Sint8>& out) const
411 {
412 // Class opening element:
413
414 out << "<CLASS ";
415 out << " NAME=\"" << _className << "\" ";
416
417 if (_superClassName.size())
418 out << " SUPERCLASS=\"" << _superClassName << "\" ";
419
420 out << ">\n";
421 mike 1.18
422 // Qualifiers:
423
424 _qualifiers.toXml(out);
425
426 // Parameters:
427
428 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
429 _properties[i].toXml(out);
430
431 // Methods:
432
433 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
434 _methods[i].toXml(out);
435
436 // Class closing element:
437
438 out << "</CLASS>\n";
439 }
|