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

  1 mike  1.15 //%/////////////////////////////////////////////////////////////////////////////
  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.15 //
 23            // Author: Mike Brasher (mbrasher@bmc.com)
 24            //
 25 karl  1.24 // Modified By:	Karl Schopmeyer (k.schopmeyer@opengroup.org)
 26 mike  1.15 //
 27            //%/////////////////////////////////////////////////////////////////////////////
 28            
 29            #include "CIMQualifierList.h"
 30            #include "DeclContext.h"
 31            #include "CIMQualifierDecl.h"
 32            #include "CIMName.h"
 33            #include "Indentor.h"
 34            #include "XmlWriter.h"
 35 karl  1.29 #include <Pegasus/Common/Tracer.h>
 36 mike  1.15 
 37            PEGASUS_NAMESPACE_BEGIN
 38 karl  1.18 PEGASUS_USING_STD;
 39 mike  1.15 
 40            CIMQualifierList::CIMQualifierList()
 41            {
 42            
 43            }
 44            
 45            CIMQualifierList::~CIMQualifierList()
 46            {
 47            
 48            }
 49            
 50            CIMQualifierList& CIMQualifierList::add(const CIMQualifier& qualifier)
 51            {
 52 kumpf 1.32     if (qualifier.isNull())
 53 kumpf 1.31 	throw UninitializedHandle();
 54 mike  1.15 
 55                if (find(qualifier.getName()) != PEG_NOT_FOUND)
 56            	throw AlreadyExists();
 57            
 58                _qualifiers.append(qualifier);
 59            
 60                return *this;
 61            }
 62            //ATTN: Why do we not do the outofbounds check here. KS 18 May 2k
 63            CIMQualifier& CIMQualifierList::getQualifier(Uint32 pos)
 64            {
 65                return _qualifiers[pos];
 66            }
 67            
 68            //ATTN: added ks 18 may 2001. Should we have outofbounds?
 69            void CIMQualifierList::removeQualifier(Uint32 pos)
 70            {
 71                _qualifiers.remove(pos);
 72            }
 73            
 74            Uint32 CIMQualifierList::find(const String& name) const
 75 mike  1.15 {
 76                for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
 77                {
 78            	if (CIMName::equal(_qualifiers[i].getName(), name))
 79            	    return i;
 80                }
 81            
 82                return PEG_NOT_FOUND;
 83            }
 84 karl  1.28 Boolean CIMQualifierList::isTrue(const String& name) const
 85            {
 86                Uint32 pos = find(name);
 87            
 88                if (pos == PEG_NOT_FOUND)
 89            	return false;
 90            
 91                Boolean flag;
 92                const CIMValue& value = getQualifier(pos).getValue();
 93            
 94                if (value.getType() != CIMType::BOOLEAN)
 95            	return false;
 96            
 97                value.get(flag);
 98                return flag;
 99            }
100 mike  1.15 
101            Uint32 CIMQualifierList::findReverse(const String& name) const
102            {
103                for (Uint32 i = _qualifiers.size(); i; --i)
104                {
105            	if (CIMName::equal(_qualifiers[i - 1].getName(), name))
106            	    return i - 1;
107                }
108            
109                return PEG_NOT_FOUND;
110            }
111            
112            void CIMQualifierList::resolve(
113                DeclContext* declContext,
114                const String& nameSpace,
115 karl  1.29     Uint32 scope, 			 // Scope of the entity being resolved.
116 mike  1.15     Boolean isInstancePart,
117 mike  1.23     CIMQualifierList& inheritedQualifiers,
118 karl  1.25     Boolean propagateQualifiers)	// Apparently not used ks 24 mar 2002
119 mike  1.15 {
120 karl  1.29     PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMQualifierList::resolve()");
121 mike  1.15     // For each qualifier in the qualifiers array, the following
122                // is checked:
123                //
124                //     1. Whether it is declared (can be obtained from the declContext).
125                //
126                //     2. Whether it has the same type as the declaration.
127                //
128 karl  1.24     //	   3. Whether the qualifier is valid for the given scope.
129 mike  1.15     //
130                //	   4. Whether the qualifier can be overriden (the flavor is
131                //	      ENABLEOVERRIDE on the corresponding reference qualifier).
132                //
133                //	   5. Whether the qualifier should be propagated to the subclass.
134                //
135                // If the qualifier should be overriden, then it is injected into the
136                // qualifiers array (from the inheritedQualifiers array).
137            
138                for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
139                {
140 karl  1.24 		CIMQualifier q = _qualifiers[i];
141            		//----------------------------------------------------------------------
142            		// 1. Check to see if it's declared.
143            		//----------------------------------------------------------------------
144 karl  1.27 		// set this back to  CIMConstQualifierDecl
145            		CIMQualifierDecl qd = declContext->lookupQualifierDecl(
146 karl  1.24 			nameSpace, q.getName());
147            	
148 kumpf 1.32 		if (qd.isNull())
149 karl  1.24 			throw UndeclaredQualifier(q.getName());
150            	
151            		//----------------------------------------------------------------------
152            		// 2. Check the type and isArray.  Must be the same:
153            		//----------------------------------------------------------------------
154            	
155            		if (!(q.getType() == qd.getType() && q.isArray() == qd.isArray()))
156            			throw BadQualifierType(q.getName());
157            	
158            		//----------------------------------------------------------------------
159            		// 3. Check the scope: Must be legal for this qualifier
160            		//----------------------------------------------------------------------
161            //#if 0
162            			// ATTN:  These lines throw a bogus exception if the qualifier has
163            			// a valid scope (such as Scope::ASSOCIATION) which is not Scope::CLASS
164            			// ks Mar 2002. Reinstalled 23 March 2002 to test.
165            
166            		if (!(qd.getScope() & scope))
167            			throw BadQualifierScope(qd.getName(), ScopeToString(scope));
168            //#endif
169            		//----------------------------------------------------------------------
170 karl  1.27 		// Resolve the qualifierflavor. Since Flavors are a combination of inheritance
171            		// and input characteristics, resolve the inherited characteristics
172            		// against those provided with the creation.  If there is a superclass
173            		// the flavor is resolved against that superclass.  If not, it is resolved
174            		// against the declaration. If the flavor is disableoverride and tosubclass
175            		// the resolved qualifier value must be identical to the original
176 karl  1.24 		//----------------------------------------------------------------------
177 karl  1.27 		// Test for Qualifier found in SuperClass. If found and qualifier
178            		// is not overridable.
179            		// Abstract (not Overridable and restricted) can be found in subclasses
180            		// Can have nonabstracts below abstracts. That is function of nottosubclass
181            		// Association (notOverridable and tosubclass) can be found in subclasses but
182            		// cannot be changed. No non-associatons below associations. In other words
183            		// once a class becomes an association, no subclass can override that definition
184            		// apparently
185            		// Throw exception if DisableOverride and tosubclass and different value.
186            		// Gets the source from superclass if qualifier exists or from declaraction
187            		// If we do not throw the exception, resolve the flavor from the inheritance
188            		// point and resolve against current input.
189            		// Diableoverride is defined in the CIM Spec to mean that the value cannot change
190            		// The other characteristics including the flavor can change apparently. Thus, we
191            		// need only confirm that the value is the same (2.2 pp 33).  Strange since we 
192            		// would think that  override implies that you cannot override any of the 
193            		// characteristics (value, type, flavor, etc.) This also leaves the question
194            		// of NULL or no values.  The implication is that we must move the value
195            		// from the superclass or declaration.
196            
197 karl  1.24 		Uint32 pos = inheritedQualifiers.find(q.getName());
198 karl  1.25 
199            		//cout << "KSTEST Qualifier resolve inherit test " << q.getName() 
200 karl  1.27 		//<< " Inherited From " << ((pos == PEG_NOT_FOUND) ? "Declaration" : "superclass")
201            		//<< " Flavor " << q.getFlavor() 
202            		//<< " inherited Flavor ";
203 karl  1.25 
204 karl  1.27 		if (pos == PEG_NOT_FOUND)
205            		{   // Qualifier does not exist in superclass
206            			/* If from declaration, we can override the default value.
207            			   However, we need some way to get the value if we have a Null.
208 karl  1.26 			if (!qd.isFlavor(CIMFlavor::OVERRIDABLE) && qd.isFlavor(CIMFlavor::TOSUBCLASS))
209 karl  1.27 			{
210            				if(!(q.getValue() == qd.getValue()))
211            					cout << "KSTEST QL err NSCL " << q.getName()
212            					<< " decl flavor " << qd.getFlavor() << " Flavor " << q.getFlavor()
213            					<< " Not override " << !qd.isFlavor(CIMFlavor::OVERRIDABLE)
214            					<< " tosubclass " <<  qd.isFlavor(CIMFlavor::TOSUBCLASS) << endl;
215 kumpf 1.33 				XmlWriter::printQualifierDeclElement(qd);
216            				XmlWriter::printQualifierElement(q);
217 karl  1.27 					//throw BadQualifierOverride(q.getName());
218            			}
219            			//cout <<  qd.getFlavor() << endl;*/
220            			// Do not allow change from disable override to enable override.
221            			if(!qd.isFlavor(CIMFlavor::OVERRIDABLE) && q.isFlavor(CIMFlavor::OVERRIDABLE ))
222            				throw BadQualifierOverride(q.getName());
223            
224            			q.resolveFlavor(qd.getFlavor(), false);
225            			/*if(!(q.getValue() == qd.getValue()))
226            				cout << "KSTEST Flavor resolved from decl. " << q.getName()
227            				<< " decl flavor " << qd.getFlavor() << " Flavor " << q.getFlavor()
228            				<< " Not override " << !qd.isFlavor(CIMFlavor::OVERRIDABLE)
229            				<< " tosubclass " <<  qd.isFlavor(CIMFlavor::TOSUBCLASS) << endl;            
230 kumpf 1.33 			 XmlWriter::printQualifierDeclElement(qd);
231            			 XmlWriter::printQualifierElement(q); */
232 karl  1.27 		}
233            		else   			// qualifier exists in superclass 
234            		{	////// Make Const again
235            			CIMQualifier iq = inheritedQualifiers.getQualifier(pos);
236            			// don't allow change override to notoverride.
237            			if(!iq.isFlavor(CIMFlavor::OVERRIDABLE) && q.isFlavor(CIMFlavor::OVERRIDABLE ))
238            				throw BadQualifierOverride(q.getName());
239            			
240            			if (!iq.isFlavor(CIMFlavor::OVERRIDABLE) && iq.isFlavor(CIMFlavor::TOSUBCLASS))
241            			{
242            				/*if(!(q.getValue() == iq.getvalue()))
243            					cout << "KSTEST QL err inherit " << q.getName()
244            					<< " from superclass " << iq.getName() 
245            					<< "   Superclass flavor " << iq.getFlavor()
246            					<< " Flavor " << q.getFlavor() 
247            					<< endl;
248 kumpf 1.33 			        XmlWriter::printQualifierElement(iq);
249            			        XmlWriter::printQualifierElement(q); */
250 karl  1.27 				// test if values the same.
251            				CIMValue qv = q.getValue();
252            				CIMValue iqv = iq.getValue();
253            				if(!(qv == iqv)) {
254 karl  1.26 					throw BadQualifierOverride(q.getName());
255 karl  1.27 			  }
256            			} 
257            			//cout << iq.getFlavor()  << endl;
258            			q.resolveFlavor(iq.getFlavor(), true);	
259 karl  1.24 		}
260 karl  1.25     } 					// end of this objects qualifier loop
261 mike  1.15 
262                //--------------------------------------------------------------------------
263                // Propagate qualifiers to subclass or to instance that do not have
264                // already have those qualifiers:
265                //--------------------------------------------------------------------------
266 karl  1.29     //cout << "KSTEST. Inherited qualifiers ct = " << inheritedQualifiers.getCount() << endl;
267 karl  1.25 
268 mike  1.15     for (Uint32 i = 0, n = inheritedQualifiers.getCount(); i < n; i++)
269                {
270 karl  1.24 		CIMQualifier iq = inheritedQualifiers.getQualifier(i);
271 karl  1.29 		//cout << "KSTEST inherited qualifier propagate loop " <<  iq.getName() 
272            		//<< " flavor " << iq.getFlavor << " count " << i << endl;
273            	
274 karl  1.24 		if (isInstancePart)
275            		{
276            			if (!iq.isFlavor(CIMFlavor::TOINSTANCE))
277            				continue;
278            		}
279            		else
280            		{
281            			if (!iq.isFlavor(CIMFlavor::TOSUBCLASS))
282            				continue;
283            		}
284            		
285            		// If the qualifiers list does not already contain this qualifier,
286 karl  1.25 		// then propagate it (and set the propagated flag to true).	 Else we
287            		// keep current value. Note we have already eliminated any possibity that
288            		// a nonoverridable qualifier can be in the list.
289            		// Note that there is no exists() function ATTN:KS 25 Mar 2002
290            		if(find(iq.getName()) != PEG_NOT_FOUND)
291 karl  1.24 			continue;
292            			
293            		CIMQualifier q = iq.clone();
294            		q.setPropagated(true);
295            		_qualifiers.prepend(q);
296 mike  1.15     }
297            }
298            
299            void CIMQualifierList::toXml(Array<Sint8>& out) const
300            {
301                for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
302 kumpf 1.33 	XmlWriter::appendQualifierElement(out, _qualifiers[i]);
303 mike  1.15 }
304            
305 mike  1.17 /** toMof - Generates MOF output for a list of CIM Qualifiers.
306                The qualifiers may be class, property, parameter, etc.
307                The BNF for this is:
308                <pre>
309                qualifierList       = "[" qualifier *( "," qualifier ) "]"
310                </pre>
311                Produces qualifiers as a string on without nl.
312                */
313            void CIMQualifierList::toMof(Array<Sint8>& out) const
314            {
315                // if no qualifiers, return
316                if (_qualifiers.size() == 0)
317            	return;
318            
319                // Qualifier leading bracket.
320                out <<"[";
321            
322                // Loop to list qualifiers
323                for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
324                {
325            	// if second or greater, add comma separator
326 mike  1.17 	if (i > 0)
327 karl  1.22 	    out << ", \n";
328 mike  1.17 	_qualifiers[i].toMof(out);
329                }
330                
331                // Terminating bracket
332                out << "]";
333            }
334            
335            
336 mike  1.15 void CIMQualifierList::print(PEGASUS_STD(ostream) &os) const
337            {
338                Array<Sint8> tmp;
339                toXml(tmp);
340                tmp.append('\0');
341                os << tmp.getData() << PEGASUS_STD(endl);
342            }
343            
344            Boolean CIMQualifierList::identical(const CIMQualifierList& x) const
345            {
346                Uint32 count = getCount();
347            
348                if (count != x.getCount())
349            	return false;
350            
351                for (Uint32 i = 0; i < count; i++)
352 mike  1.16     {
353            	if (!_qualifiers[i].identical(x._qualifiers[i]))
354            	    return false;
355                }
356 mike  1.15 
357                return true;
358            }
359            
360            void CIMQualifierList::cloneTo(CIMQualifierList& x) const
361            {
362                x._qualifiers.clear();
363                x._qualifiers.reserve(_qualifiers.size());
364            
365                for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
366            	x._qualifiers.append(_qualifiers[i].clone());
367            }
368            
369            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2