1 mike 1.15 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.35 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.15 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.35 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.15 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.35 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.15 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.35 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.15 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
|
26 karl 1.24 // Modified By: Karl Schopmeyer (k.schopmeyer@opengroup.org)
|
27 kumpf 1.37 // Carol Ann Krug Graves, Hewlett-Packard Company
28 // (carolann_graves@hp.com)
|
29 mike 1.15 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "CIMQualifierList.h"
33 #include "DeclContext.h"
|
34 kumpf 1.37 #include "Resolver.h"
|
35 mike 1.15 #include "CIMQualifierDecl.h"
36 #include "CIMName.h"
37 #include "Indentor.h"
38 #include "XmlWriter.h"
|
39 kumpf 1.34 #include "MofWriter.h"
|
40 karl 1.29 #include <Pegasus/Common/Tracer.h>
|
41 mike 1.15
42 PEGASUS_NAMESPACE_BEGIN
|
43 karl 1.18 PEGASUS_USING_STD;
|
44 mike 1.15
45 CIMQualifierList::CIMQualifierList()
46 {
47
48 }
49
50 CIMQualifierList::~CIMQualifierList()
51 {
52
53 }
54
55 CIMQualifierList& CIMQualifierList::add(const CIMQualifier& qualifier)
56 {
|
57 kumpf 1.40 if (qualifier.isUninitialized())
|
58 kumpf 1.44 throw UninitializedObjectException();
|
59 mike 1.15
60 if (find(qualifier.getName()) != PEG_NOT_FOUND)
|
61 kumpf 1.46 throw AlreadyExistsException
62 ("qualifier \"" + qualifier.getName().getString () + "\"");
|
63 mike 1.15
64 _qualifiers.append(qualifier);
65
66 return *this;
67 }
68 //ATTN: Why do we not do the outofbounds check here. KS 18 May 2k
|
69 kumpf 1.45 CIMQualifier& CIMQualifierList::getQualifier(Uint32 index)
|
70 mike 1.15 {
|
71 kumpf 1.45 return _qualifiers[index];
|
72 mike 1.15 }
73
74 //ATTN: added ks 18 may 2001. Should we have outofbounds?
|
75 kumpf 1.45 void CIMQualifierList::removeQualifier(Uint32 index)
|
76 mike 1.15 {
|
77 kumpf 1.45 _qualifiers.remove(index);
|
78 mike 1.15 }
79
|
80 kumpf 1.39 Uint32 CIMQualifierList::find(const CIMName& name) const
|
81 mike 1.15 {
82 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
83 {
|
84 kumpf 1.39 if (name.equal(_qualifiers[i].getName()))
|
85 mike 1.15 return i;
86 }
87
88 return PEG_NOT_FOUND;
89 }
|
90 kumpf 1.39 Boolean CIMQualifierList::isTrue(const CIMName& name) const
|
91 karl 1.28 {
|
92 kumpf 1.45 Uint32 index = find(name);
|
93 karl 1.28
|
94 kumpf 1.45 if (index == PEG_NOT_FOUND)
|
95 karl 1.28 return false;
96
97 Boolean flag;
|
98 kumpf 1.45 const CIMValue& value = getQualifier(index).getValue();
|
99 karl 1.28
|
100 kumpf 1.38 if (value.getType() != CIMTYPE_BOOLEAN)
|
101 karl 1.28 return false;
102
103 value.get(flag);
104 return flag;
105 }
|
106 mike 1.15
|
107 kumpf 1.39 Uint32 CIMQualifierList::findReverse(const CIMName& name) const
|
108 mike 1.15 {
109 for (Uint32 i = _qualifiers.size(); i; --i)
110 {
|
111 kumpf 1.39 if (name.equal(_qualifiers[i-1].getName()))
|
112 mike 1.15 return i - 1;
113 }
114
115 return PEG_NOT_FOUND;
116 }
117
118 void CIMQualifierList::resolve(
119 DeclContext* declContext,
|
120 kumpf 1.46 const CIMNamespaceName & nameSpace,
|
121 kumpf 1.41 CIMScope scope, // Scope of the entity being resolved.
|
122 mike 1.15 Boolean isInstancePart,
|
123 mike 1.23 CIMQualifierList& inheritedQualifiers,
|
124 karl 1.25 Boolean propagateQualifiers) // Apparently not used ks 24 mar 2002
|
125 mike 1.15 {
|
126 karl 1.29 PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMQualifierList::resolve()");
|
127 mike 1.15 // For each qualifier in the qualifiers array, the following
128 // is checked:
129 //
130 // 1. Whether it is declared (can be obtained from the declContext).
131 //
132 // 2. Whether it has the same type as the declaration.
133 //
|
134 karl 1.24 // 3. Whether the qualifier is valid for the given scope.
|
135 mike 1.15 //
136 // 4. Whether the qualifier can be overriden (the flavor is
137 // ENABLEOVERRIDE on the corresponding reference qualifier).
138 //
139 // 5. Whether the qualifier should be propagated to the subclass.
140 //
141 // If the qualifier should be overriden, then it is injected into the
142 // qualifiers array (from the inheritedQualifiers array).
143
144 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
145 {
|
146 karl 1.24 CIMQualifier q = _qualifiers[i];
147 //----------------------------------------------------------------------
148 // 1. Check to see if it's declared.
149 //----------------------------------------------------------------------
|
150 karl 1.27 // set this back to CIMConstQualifierDecl
151 CIMQualifierDecl qd = declContext->lookupQualifierDecl(
|
152 karl 1.24 nameSpace, q.getName());
153
|
154 kumpf 1.40 if (qd.isUninitialized())
|
155 kumpf 1.46 throw UndeclaredQualifier(q.getName().getString ());
|
156 karl 1.24
157 //----------------------------------------------------------------------
158 // 2. Check the type and isArray. Must be the same:
159 //----------------------------------------------------------------------
160
161 if (!(q.getType() == qd.getType() && q.isArray() == qd.isArray()))
|
162 kumpf 1.46 throw BadQualifierType(q.getName().getString ());
|
163 karl 1.24
164 //----------------------------------------------------------------------
165 // 3. Check the scope: Must be legal for this qualifier
166 //----------------------------------------------------------------------
167 //#if 0
168 // ATTN: These lines throw a bogus exception if the qualifier has
169 // a valid scope (such as Scope::ASSOCIATION) which is not Scope::CLASS
170 // ks Mar 2002. Reinstalled 23 March 2002 to test.
171
|
172 kumpf 1.41 if (!(qd.getScope().hasScope (scope)))
|
173 kumpf 1.46 throw BadQualifierScope
174 (qd.getName().getString (), scope.toString ());
|
175 karl 1.24 //#endif
176 //----------------------------------------------------------------------
|
177 karl 1.27 // Resolve the qualifierflavor. Since Flavors are a combination of inheritance
178 // and input characteristics, resolve the inherited characteristics
179 // against those provided with the creation. If there is a superclass
180 // the flavor is resolved against that superclass. If not, it is resolved
181 // against the declaration. If the flavor is disableoverride and tosubclass
182 // the resolved qualifier value must be identical to the original
|
183 karl 1.24 //----------------------------------------------------------------------
|
184 karl 1.27 // Test for Qualifier found in SuperClass. If found and qualifier
185 // is not overridable.
186 // Abstract (not Overridable and restricted) can be found in subclasses
187 // Can have nonabstracts below abstracts. That is function of nottosubclass
188 // Association (notOverridable and tosubclass) can be found in subclasses but
189 // cannot be changed. No non-associatons below associations. In other words
190 // once a class becomes an association, no subclass can override that definition
191 // apparently
192 // Throw exception if DisableOverride and tosubclass and different value.
193 // Gets the source from superclass if qualifier exists or from declaraction
194 // If we do not throw the exception, resolve the flavor from the inheritance
195 // point and resolve against current input.
196 // Diableoverride is defined in the CIM Spec to mean that the value cannot change
197 // The other characteristics including the flavor can change apparently. Thus, we
198 // need only confirm that the value is the same (2.2 pp 33). Strange since we
199 // would think that override implies that you cannot override any of the
200 // characteristics (value, type, flavor, etc.) This also leaves the question
201 // of NULL or no values. The implication is that we must move the value
202 // from the superclass or declaration.
203
|
204 kumpf 1.45 Uint32 index = inheritedQualifiers.find(q.getName());
|
205 karl 1.25
206 //cout << "KSTEST Qualifier resolve inherit test " << q.getName()
|
207 kumpf 1.45 //<< " Inherited From " << ((index == PEG_NOT_FOUND) ? "Declaration" : "superclass")
|
208 karl 1.27 //<< " Flavor " << q.getFlavor()
209 //<< " inherited Flavor ";
|
210 karl 1.25
|
211 kumpf 1.45 if (index == PEG_NOT_FOUND)
|
212 karl 1.27 { // Qualifier does not exist in superclass
213 /* If from declaration, we can override the default value.
214 However, we need some way to get the value if we have a Null.
|
215 kumpf 1.42 if (!(qd.getFlavor ().hasFlavor
216 (CIMFlavor::OVERRIDABLE))
217 && qd.getFlavor ().hasFlavor
218 (CIMFlavor::TOSUBCLASS))
|
219 karl 1.27 {
220 if(!(q.getValue() == qd.getValue()))
221 cout << "KSTEST QL err NSCL " << q.getName()
222 << " decl flavor " << qd.getFlavor() << " Flavor " << q.getFlavor()
|
223 kumpf 1.42 << " Not override "
224 << !(qd.getFlavor ().hasFlavor
225 (CIMFlavor::OVERRIDABLE))
226 << " tosubclass "
227 << qd.getFlavor ().hasFlavor
228 (CIMFlavor::TOSUBCLASS) << endl;
|
229 kumpf 1.33 XmlWriter::printQualifierDeclElement(qd);
230 XmlWriter::printQualifierElement(q);
|
231 karl 1.27 //throw BadQualifierOverride(q.getName());
232 }
233 //cout << qd.getFlavor() << endl;*/
234 // Do not allow change from disable override to enable override.
|
235 kumpf 1.42 if ((!qd.getFlavor ().hasFlavor
236 (CIMFlavor::OVERRIDABLE))
237 && (q.getFlavor ().hasFlavor
238 (CIMFlavor::OVERRIDABLE)))
|
239 kumpf 1.46 throw BadQualifierOverride
240 (q.getName().getString ());
|
241 karl 1.27
|
242 kumpf 1.42 Resolver::resolveQualifierFlavor
243 (q, CIMFlavor (qd.getFlavor ()), false);
|
244 karl 1.27 /*if(!(q.getValue() == qd.getValue()))
245 cout << "KSTEST Flavor resolved from decl. " << q.getName()
|
246 kumpf 1.42 << " decl flavor " << qd.getFlavor().toString ()
247 << " Flavor " << q.getFlavor().toString ()
248 << " Not override "
249 << !(qd.getFlavor ().hasFlavor
250 (CIMFlavor::OVERRIDABLE))
251 << " tosubclass " << qd.getFlavor ().hasFlavor
252 (CIMFlavor::TOSUBCLASS) << endl;
|
253 kumpf 1.33 XmlWriter::printQualifierDeclElement(qd);
254 XmlWriter::printQualifierElement(q); */
|
255 karl 1.27 }
256 else // qualifier exists in superclass
257 { ////// Make Const again
|
258 kumpf 1.45 CIMQualifier iq = inheritedQualifiers.getQualifier(index);
|
259 karl 1.27 // don't allow change override to notoverride.
|
260 kumpf 1.42 if (!(iq.getFlavor ().hasFlavor
261 (CIMFlavor::OVERRIDABLE))
262 && q.getFlavor ().hasFlavor (CIMFlavor::OVERRIDABLE))
|
263 kumpf 1.46 throw BadQualifierOverride
264 (q.getName().getString ());
|
265 karl 1.27
|
266 kumpf 1.42 if (!(iq.getFlavor ().hasFlavor
267 (CIMFlavor::OVERRIDABLE))
268 && iq.getFlavor ().hasFlavor
269 (CIMFlavor::TOSUBCLASS))
|
270 karl 1.27 {
271 /*if(!(q.getValue() == iq.getvalue()))
272 cout << "KSTEST QL err inherit " << q.getName()
273 << " from superclass " << iq.getName()
|
274 kumpf 1.42 << " Superclass flavor " << iq.getFlavor().toString ()
275 << " Flavor " << q.getFlavor().toString ()
|
276 karl 1.27 << endl;
|
277 kumpf 1.33 XmlWriter::printQualifierElement(iq);
278 XmlWriter::printQualifierElement(q); */
|
279 karl 1.27 // test if values the same.
280 CIMValue qv = q.getValue();
281 CIMValue iqv = iq.getValue();
282 if(!(qv == iqv)) {
|
283 kumpf 1.46 throw BadQualifierOverride
284 (q.getName().getString ());
|
285 karl 1.27 }
286 }
287 //cout << iq.getFlavor() << endl;
|
288 kumpf 1.42 Resolver::resolveQualifierFlavor
289 (q, CIMFlavor (iq.getFlavor ()), true);
|
290 karl 1.24 }
|
291 karl 1.25 } // end of this objects qualifier loop
|
292 mike 1.15
293 //--------------------------------------------------------------------------
294 // Propagate qualifiers to subclass or to instance that do not have
295 // already have those qualifiers:
296 //--------------------------------------------------------------------------
|
297 karl 1.29 //cout << "KSTEST. Inherited qualifiers ct = " << inheritedQualifiers.getCount() << endl;
|
298 karl 1.25
|
299 mike 1.15 for (Uint32 i = 0, n = inheritedQualifiers.getCount(); i < n; i++)
300 {
|
301 karl 1.24 CIMQualifier iq = inheritedQualifiers.getQualifier(i);
|
302 karl 1.29 //cout << "KSTEST inherited qualifier propagate loop " << iq.getName()
303 //<< " flavor " << iq.getFlavor << " count " << i << endl;
304
|
305 karl 1.24 if (isInstancePart)
306 {
|
307 kumpf 1.42 if (!(iq.getFlavor ().hasFlavor
308 (CIMFlavor::TOINSTANCE)))
|
309 karl 1.24 continue;
310 }
311 else
312 {
|
313 kumpf 1.42 if (!(iq.getFlavor ().hasFlavor
314 (CIMFlavor::TOSUBCLASS)))
|
315 karl 1.24 continue;
316 }
317
318 // If the qualifiers list does not already contain this qualifier,
|
319 karl 1.25 // then propagate it (and set the propagated flag to true). Else we
320 // keep current value. Note we have already eliminated any possibity that
321 // a nonoverridable qualifier can be in the list.
322 // Note that there is no exists() function ATTN:KS 25 Mar 2002
323 if(find(iq.getName()) != PEG_NOT_FOUND)
|
324 karl 1.24 continue;
325
326 CIMQualifier q = iq.clone();
327 q.setPropagated(true);
328 _qualifiers.prepend(q);
|
329 mike 1.15 }
330 }
331
332 void CIMQualifierList::toXml(Array<Sint8>& out) const
333 {
334 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
|
335 kumpf 1.33 XmlWriter::appendQualifierElement(out, _qualifiers[i]);
|
336 mike 1.15 }
337
|
338 mike 1.17 /** toMof - Generates MOF output for a list of CIM Qualifiers.
339 The qualifiers may be class, property, parameter, etc.
340 The BNF for this is:
341 <pre>
342 qualifierList = "[" qualifier *( "," qualifier ) "]"
343 </pre>
344 Produces qualifiers as a string on without nl.
345 */
346 void CIMQualifierList::toMof(Array<Sint8>& out) const
347 {
348 // if no qualifiers, return
349 if (_qualifiers.size() == 0)
350 return;
351
352 // Qualifier leading bracket.
353 out <<"[";
354
355 // Loop to list qualifiers
356 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
357 {
358 // if second or greater, add comma separator
359 mike 1.17 if (i > 0)
|
360 karl 1.22 out << ", \n";
|
361 kumpf 1.34 MofWriter::appendQualifierElement(out, _qualifiers[i]);
|
362 mike 1.17 }
363
364 // Terminating bracket
365 out << "]";
366 }
367
368
|
369 mike 1.15 void CIMQualifierList::print(PEGASUS_STD(ostream) &os) const
370 {
371 Array<Sint8> tmp;
372 toXml(tmp);
373 tmp.append('\0');
374 os << tmp.getData() << PEGASUS_STD(endl);
375 }
376
377 Boolean CIMQualifierList::identical(const CIMQualifierList& x) const
378 {
379 Uint32 count = getCount();
380
381 if (count != x.getCount())
382 return false;
383
384 for (Uint32 i = 0; i < count; i++)
|
385 mike 1.16 {
386 if (!_qualifiers[i].identical(x._qualifiers[i]))
387 return false;
388 }
|
389 mike 1.15
390 return true;
391 }
392
393 void CIMQualifierList::cloneTo(CIMQualifierList& x) const
394 {
395 x._qualifiers.clear();
|
396 kumpf 1.36 x._qualifiers.reserveCapacity(_qualifiers.size());
|
397 mike 1.15
398 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
399 x._qualifiers.append(_qualifiers[i].clone());
400 }
401
402 PEGASUS_NAMESPACE_END
|