(file) Return to CIMClassRep.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2