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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2