1 //%/////////////////////////////////////////////////////////////////////////////
\r
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
\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
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
21 //==============================================================================
\r
23 // Author: Mike Brasher (mbrasher@bmc.com)
\r
27 //%/////////////////////////////////////////////////////////////////////////////
\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
36 PEGASUS_NAMESPACE_BEGIN
\r
38 CIMClassRep::CIMClassRep(
\r
39 const String& className,
\r
40 const String& superClassName)
\r
41 : _className(className), _superClassName(superClassName), _resolved(false)
\r
43 if (!CIMName::legal(className))
\r
44 throw IllegalName();
\r
46 if (superClassName.size() && !CIMName::legal(superClassName))
\r
47 throw IllegalName();
\r
50 CIMClassRep::~CIMClassRep()
\r
55 Boolean CIMClassRep::isAssociation() const
\r
57 Uint32 pos = findQualifier(CIMQualifierNames::ASSOCIATION);
\r
59 if (pos == PEG_NOT_FOUND)
\r
64 const CIMValue& value = getQualifier(pos).getValue();
\r
66 if (value.getType() != CIMType::BOOLEAN)
\r
73 Boolean CIMClassRep::isAbstract() const
\r
75 Uint32 pos = findQualifier(CIMQualifierNames::ABSTRACT);
\r
77 if (pos == PEG_NOT_FOUND)
\r
81 const CIMValue& value = getQualifier(pos).getValue();
\r
83 if (value.getType() != CIMType::BOOLEAN)
\r
90 void CIMClassRep::setSuperClassName(const String& superClassName)
\r
92 if (!CIMName::legal(superClassName))
\r
93 throw IllegalName();
\r
95 _superClassName = superClassName;
\r
98 void CIMClassRep::addProperty(const CIMProperty& x)
\r
101 throw UnitializedHandle();
\r
103 // Reject addition of duplicate property name:
\r
105 if (findProperty(x.getName()) != PEG_NOT_FOUND)
\r
106 throw AlreadyExists();
\r
108 // Reject addition of references to non-associations:
\r
110 if (!isAssociation() && x.getValue().getType() == CIMType::REFERENCE)
\r
111 throw AddedReferenceToClass(_className);
\r
113 // Set the class origin:
\r
114 // ATTN: put this check in other places:
\r
116 if (x.getClassOrigin().size() == 0)
\r
117 CIMProperty(x).setClassOrigin(_className);
\r
119 // Add the property:
\r
121 _properties.append(x);
\r
125 Uint32 CIMClassRep::findProperty(const String& name)
\r
127 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
\r
129 if (CIMName::equal(_properties[i].getName(), name))
\r
133 return PEG_NOT_FOUND;
\r
136 Boolean CIMClassRep::existsProperty(const String& name)
\r
138 return (findProperty(name) != PEG_NOT_FOUND) ?
\r
142 CIMProperty CIMClassRep::getProperty(Uint32 pos)
\r
144 if (pos >= _properties.size())
\r
145 throw OutOfBounds();
\r
147 return _properties[pos];
\r
150 void CIMClassRep::removeProperty(Uint32 pos)
\r
152 if (pos >= _properties.size())
\r
153 throw OutOfBounds();
\r
155 _properties.remove(pos);
\r
159 Uint32 CIMClassRep::getPropertyCount() const
\r
161 return _properties.size();
\r
164 void CIMClassRep::addMethod(const CIMMethod& x)
\r
167 throw UnitializedHandle();
\r
169 // Reject duplicate method names:
\r
171 if (findMethod(x.getName()) != PEG_NOT_FOUND)
\r
172 throw AlreadyExists();
\r
176 _methods.append(x);
\r
179 Uint32 CIMClassRep::findMethod(const String& name)
\r
181 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
\r
183 if (CIMName::equal(_methods[i].getName(), name))
\r
187 return PEG_NOT_FOUND;
\r
190 Boolean CIMClassRep::existsMethod(const String& name)
\r
192 return(findMethod(name) != PEG_NOT_FOUND) ?
\r
195 CIMMethod CIMClassRep::getMethod(Uint32 pos)
\r
197 if (pos >= _methods.size())
\r
198 throw OutOfBounds();
\r
200 return _methods[pos];
\r
203 Uint32 CIMClassRep::getMethodCount() const
\r
205 return _methods.size();
\r
208 void CIMClassRep::removeMethod(Uint32 pos)
\r
210 if (pos >= _methods.size())
\r
211 throw OutOfBounds();
\r
213 _methods.remove(pos);
\r
216 void CIMClassRep::resolve(
\r
217 DeclContext* context,
\r
218 const String& nameSpace)
\r
222 throw ClassAlreadyResolved(_className);
\r
226 throw NullPointer();
\r
228 if (_superClassName.size())
\r
230 //----------------------------------------------------------------------
\r
231 // First check to see if the super-class really exists:
\r
232 //----------------------------------------------------------------------
\r
234 CIMConstClass superClass
\r
235 = context->lookupClass(nameSpace, _superClassName);
\r
238 throw PEGASUS_CIM_EXCEPTION(INVALID_SUPERCLASS, _superClassName);
\r
241 if (!superClass._rep->_resolved)
\r
242 throw ClassNotResolved(_superClassName);
\r
245 //----------------------------------------------------------------------
\r
246 // Iterate all the properties of *this* class. Resolve each one and
\r
247 // set the class-origin:
\r
248 //----------------------------------------------------------------------
\r
250 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
\r
252 CIMProperty& property = _properties[i];
\r
253 Uint32 pos = superClass.findProperty(property.getName());
\r
255 if (pos == PEG_NOT_FOUND)
\r
257 property.resolve(context, nameSpace, false);
\r
261 CIMConstProperty superClassProperty =
\r
262 superClass.getProperty(pos);
\r
263 property.resolve(context, nameSpace, false, superClassProperty);
\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
272 // Iterate super-class properties:
\r
274 for (Uint32 i = 0, m = 0, n = superClass.getPropertyCount(); i < n; i++)
\r
276 CIMConstProperty superClassProperty = superClass.getProperty(i);
\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
282 Uint32 pos = PEG_NOT_FOUND;
\r
284 for (Uint32 j = m, n = _properties.size(); j < n; j++)
\r
286 if (CIMName::equal(
\r
287 _properties[j].getName(),
\r
288 superClassProperty.getName()))
\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
299 if (pos == PEG_NOT_FOUND)
\r
301 CIMProperty property = superClassProperty.clone();
\r
302 property.setPropagated(true);
\r
303 _properties.insert(m++, property);
\r
307 //----------------------------------------------------------------------
\r
308 // Iterate all the methods of *this* class. Resolve each one and
\r
309 // set the class-origin:
\r
310 //----------------------------------------------------------------------
\r
312 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
\r
314 CIMMethod& method = _methods[i];
\r
315 Uint32 pos = superClass.findMethod(method.getName());
\r
317 if (pos == PEG_NOT_FOUND)
\r
319 method.resolve(context, nameSpace);
\r
323 CIMConstMethod superClassMethod = superClass.getMethod(pos);
\r
324 method.resolve(context, nameSpace, superClassMethod);
\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
333 for (Uint32 i = 0, m = 0, n = superClass.getMethodCount(); i < n; i++)
\r
335 CIMConstMethod superClassMethod = superClass.getMethod(i);
\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
341 Uint32 pos = PEG_NOT_FOUND;
\r
343 for (Uint32 j = m, n = _methods.size(); j < n; j++)
\r
345 if (CIMName::equal(
\r
346 _methods[j].getName(),
\r
347 superClassMethod.getName()))
\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
358 if (pos == PEG_NOT_FOUND)
\r
360 CIMMethod method = superClassMethod.clone();
\r
361 method.setPropagated(true);
\r
362 _methods.insert(m++, method);
\r
366 //----------------------------------------------------------------------
\r
367 // Validate the qualifiers of this class:
\r
368 //----------------------------------------------------------------------
\r
370 _qualifiers.resolve(
\r
373 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
\r
375 superClass._rep->_qualifiers);
\r
379 //----------------------------------------------------------------------
\r
380 // Resolve each property:
\r
381 //----------------------------------------------------------------------
\r
383 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
\r
384 _properties[i].resolve(context, nameSpace, false);
\r
386 //----------------------------------------------------------------------
\r
387 // Resolve each method:
\r
388 //----------------------------------------------------------------------
\r
390 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
\r
391 _methods[i].resolve(context, nameSpace);
\r
393 //----------------------------------------------------------------------
\r
394 // Resolve the qualifiers:
\r
395 //----------------------------------------------------------------------
\r
397 CIMQualifierList dummy;
\r
399 _qualifiers.resolve(
\r
402 isAssociation() ? CIMScope::ASSOCIATION : CIMScope::CLASS,
\r
407 // _resolved = true;
\r
410 void CIMClassRep::toXml(Array<Sint8>& out) const
\r
412 // Class opening element:
\r
415 out << " NAME=\"" << _className << "\" ";
\r
417 if (_superClassName.size())
\r
418 out << " SUPERCLASS=\"" << _superClassName << "\" ";
\r
424 _qualifiers.toXml(out);
\r
428 for (Uint32 i = 0, n = _properties.size(); i < n; i++)
\r
429 _properties[i].toXml(out);
\r
433 for (Uint32 i = 0, n = _methods.size(); i < n; i++)
\r
434 _methods[i].toXml(out);
\r
436 // Class closing element:
\r
438 out << "</CLASS>\n";
\r
441 void CIMClassRep::print(PEGASUS_STD(ostream) &os) const
\r
446 XmlWriter::indentedPrint(os, tmp.getData(), 4);
\r
447 // cout << tmp.getData() << endl;
\r
450 CIMClassRep::CIMClassRep()
\r
455 CIMClassRep::CIMClassRep(const CIMClassRep& x) :
\r
457 _className(x._className),
\r
458 _superClassName(x._superClassName),
\r
459 _resolved(x._resolved)
\r
461 x._qualifiers.cloneTo(_qualifiers);
\r
463 _properties.reserve(x._properties.size());
\r
465 for (Uint32 i = 0, n = x._properties.size(); i < n; i++)
\r
466 _properties.append(x._properties[i].clone());
\r
468 _methods.reserve(x._methods.size());
\r
470 for (Uint32 i = 0, n = x._methods.size(); i < n; i++)
\r
471 _methods.append(x._methods[i].clone());
\r
474 CIMClassRep& CIMClassRep::operator=(const CIMClassRep& x)
\r
479 Boolean CIMClassRep::identical(const CIMClassRep* x) const
\r
481 if (_className != x->_className)
\r
484 if (_superClassName != x->_superClassName)
\r
487 if (!_qualifiers.identical(x->_qualifiers))
\r
490 // Compare properties:
\r
493 const Array<CIMProperty>& tmp1 = _properties;
\r
494 const Array<CIMProperty>& tmp2 = x->_properties;
\r
496 if (tmp1.size() != tmp2.size())
\r
499 for (Uint32 i = 0, n = tmp1.size(); i < n; i++)
\r
501 if (!tmp1[i].identical(tmp2[i]))
\r
506 // Compare methods:
\r
509 const Array<CIMMethod>& tmp1 = _methods;
\r
510 const Array<CIMMethod>& tmp2 = x->_methods;
\r
512 if (tmp1.size() != tmp2.size())
\r
515 for (Uint32 i = 0, n = tmp1.size(); i < n; i++)
\r
517 if (!tmp1[i].identical(tmp2[i]))
\r
520 if (tmp1[i].getClassOrigin() != tmp2[i].getClassOrigin())
\r
523 if (tmp1[i].getPropagated() != tmp2[i].getPropagated())
\r
528 if (_resolved != x->_resolved)
\r
534 void CIMClassRep::getKeyNames(Array<String>& keyNames) const
\r
538 for (Uint32 i = 0, n = getPropertyCount(); i < n; i++)
\r
540 CIMConstProperty property = getProperty(i);
\r
542 if (property.isKey())
\r
543 keyNames.append(property.getName());
\r
547 PEGASUS_NAMESPACE_END
\r