1 martin 1.70 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.71 //
|
3 martin 1.70 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.71 //
|
10 martin 1.70 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.71 //
|
17 martin 1.70 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.71 //
|
20 martin 1.70 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.71 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.70 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.71 //
|
28 martin 1.70 //////////////////////////////////////////////////////////////////////////
|
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 "XmlWriter.h"
|
38 karl 1.29 #include <Pegasus/Common/Tracer.h>
|
39 kumpf 1.59 #include <Pegasus/Common/MessageLoader.h>
|
40 mike 1.53 #include "StrLit.h"
|
41 mike 1.54 #include "ArrayIterator.h"
|
42 marek 1.63 #include "CIMQualifierRep.h"
|
43 mike 1.15
44 PEGASUS_NAMESPACE_BEGIN
|
45 karl 1.18 PEGASUS_USING_STD;
|
46 mike 1.15
|
47 marek 1.63 static CIMName _KEY("Key");
48
|
49 kumpf 1.72 CIMQualifierList::CIMQualifierList() :
|
50 marek 1.63 _keyIndex(PEGASUS_ORDEREDSET_INDEX_UNKNOWN)
|
51 mike 1.15 {
52
53 }
54
55 CIMQualifierList::~CIMQualifierList()
56 {
57
58 }
59
60 CIMQualifierList& CIMQualifierList::add(const CIMQualifier& qualifier)
61 {
|
62 kumpf 1.40 if (qualifier.isUninitialized())
|
63 kumpf 1.57 throw UninitializedObjectException();
|
64 mike 1.15
|
65 kumpf 1.59 if (find(qualifier.getName()) != PEG_NOT_FOUND)
66 {
|
67 humberto 1.47 MessageLoaderParms parms("Common.CIMQualifierList.QUALIFIER",
|
68 kumpf 1.57 "qualifier \"$0\"",
69 qualifier.getName().getString());
|
70 humberto 1.47 throw AlreadyExistsException(parms);
71 }
|
72 mike 1.15
73 _qualifiers.append(qualifier);
|
74 kumpf 1.72
|
75 marek 1.63 // Update key index:
|
76 kumpf 1.72 if (_keyIndex == PEGASUS_ORDEREDSET_INDEX_UNKNOWN &&
|
77 marek 1.63 qualifier._rep->_name == _KEY)
78 _keyIndex = _qualifiers.size()-1;
|
79 mike 1.15
80 return *this;
81 }
|
82 kumpf 1.62
|
83 kumpf 1.45 CIMQualifier& CIMQualifierList::getQualifier(Uint32 index)
|
84 mike 1.15 {
|
85 kumpf 1.45 return _qualifiers[index];
|
86 mike 1.15 }
87
|
88 kumpf 1.45 void CIMQualifierList::removeQualifier(Uint32 index)
|
89 mike 1.15 {
|
90 kumpf 1.45 _qualifiers.remove(index);
|
91 marek 1.63 _keyIndex = PEGASUS_ORDEREDSET_INDEX_UNKNOWN;
|
92 mike 1.15 }
93
|
94 kumpf 1.62 void CIMQualifierList::clear()
95 {
96 _qualifiers.clear();
97 }
98
|
99 kumpf 1.39 Uint32 CIMQualifierList::find(const CIMName& name) const
|
100 mike 1.15 {
|
101 marek 1.63 return _qualifiers.find(name, generateCIMNameTag(name));
102 }
|
103 mike 1.15
|
104 kumpf 1.39 Boolean CIMQualifierList::isTrue(const CIMName& name) const
|
105 karl 1.28 {
|
106 kumpf 1.45 Uint32 index = find(name);
|
107 karl 1.28
|
108 kumpf 1.45 if (index == PEG_NOT_FOUND)
|
109 kumpf 1.57 return false;
|
110 karl 1.28
111 Boolean flag;
|
112 kumpf 1.45 const CIMValue& value = getQualifier(index).getValue();
|
113 karl 1.28
|
114 kumpf 1.38 if (value.getType() != CIMTYPE_BOOLEAN)
|
115 kumpf 1.57 return false;
|
116 karl 1.28
117 value.get(flag);
118 return flag;
119 }
|
120 mike 1.15
121 void CIMQualifierList::resolve(
122 DeclContext* declContext,
|
123 kumpf 1.46 const CIMNamespaceName & nameSpace,
|
124 a.dunfey 1.56 CIMScope scope, // Scope of the entity being resolved.
|
125 mike 1.15 Boolean isInstancePart,
|
126 mike 1.23 CIMQualifierList& inheritedQualifiers,
|
127 kumpf 1.68 Boolean propagateQualifiers)
|
128 mike 1.15 {
|
129 marek 1.63 _keyIndex = PEGASUS_ORDEREDSET_INDEX_UNKNOWN;
130
|
131 karl 1.29 PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMQualifierList::resolve()");
|
132 mike 1.15 // For each qualifier in the qualifiers array, the following
133 // is checked:
134 //
135 // 1. Whether it is declared (can be obtained from the declContext).
136 //
137 // 2. Whether it has the same type as the declaration.
138 //
|
139 a.dunfey 1.56 // 3. Whether the qualifier is valid for the given scope.
|
140 mike 1.15 //
|
141 a.dunfey 1.56 // 4. Whether the qualifier can be overriden (the flavor is
142 // ENABLEOVERRIDE on the corresponding reference qualifier).
|
143 mike 1.15 //
|
144 a.dunfey 1.56 // 5. Whether the qualifier should be propagated to the subclass.
|
145 mike 1.15 //
146 // If the qualifier should be overriden, then it is injected into the
147 // qualifiers array (from the inheritedQualifiers array).
148
149 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
150 {
|
151 a.dunfey 1.56 CIMQualifier q = _qualifiers[i];
152 //----------------------------------------------------------------------
153 // 1. Check to see if it's declared.
154 //----------------------------------------------------------------------
155 // set this back to CIMConstQualifierDecl
156 CIMQualifierDecl qd = declContext->lookupQualifierDecl(
157 nameSpace, q.getName());
|
158 kumpf 1.57
|
159 a.dunfey 1.56 if (qd.isUninitialized())
|
160 marek 1.60 {
161 PEG_METHOD_EXIT();
|
162 a.dunfey 1.56 throw UndeclaredQualifier(q.getName().getString ());
|
163 marek 1.60 }
|
164 kumpf 1.57
|
165 a.dunfey 1.56 //----------------------------------------------------------------------
166 // 2. Check the type and isArray. Must be the same:
167 //----------------------------------------------------------------------
|
168 kumpf 1.57
|
169 a.dunfey 1.56 if (!(q.getType() == qd.getType() && q.isArray() == qd.isArray()))
|
170 marek 1.60 {
171 PEG_METHOD_EXIT();
|
172 a.dunfey 1.56 throw BadQualifierType(q.getName().getString ());
|
173 marek 1.60 }
|
174 kumpf 1.57
|
175 a.dunfey 1.56 //----------------------------------------------------------------------
176 // 3. If the qualifier is the EmbeddedInstance qualifier, then check
177 // that the class specified by the qualifier exists in the namespace.
178 //----------------------------------------------------------------------
|
179 thilo.boehm 1.66 if (q.getName().equal(PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE))
|
180 a.dunfey 1.56 {
181 String className;
182 q.getValue().get(className);
183 CIMClass classDef = declContext->lookupClass(nameSpace,
|
184 sahana.prabhakar 1.73 CIMName(className));
|
185 kumpf 1.59 if (classDef.isUninitialized())
|
186 a.dunfey 1.56 {
|
187 marek 1.60 PEG_METHOD_EXIT();
|
188 sahana.prabhakar 1.73 throw BadQualifierType(
189 PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE.getString(),
190 className);
|
191 a.dunfey 1.56 }
192 }
193
194 //----------------------------------------------------------------------
195 // 4. Check the scope: Must be legal for this qualifier
196 //----------------------------------------------------------------------
|
197 kumpf 1.57 // ATTN: These lines throw a bogus exception if the qualifier has
198 // a valid scope (such as Scope::ASSOCIATION) which is not Scope::CLASS
199 // ks Mar 2002. Reinstalled 23 March 2002 to test.
|
200 a.dunfey 1.56
201 if (!(qd.getScope().hasScope (scope)))
|
202 marek 1.60 {
203 PEG_METHOD_EXIT();
|
204 a.dunfey 1.56 throw BadQualifierScope
205 (qd.getName().getString (), scope.toString ());
|
206 marek 1.60 }
|
207 kumpf 1.57
|
208 a.dunfey 1.56 //----------------------------------------------------------------------
|
209 kumpf 1.57 // Resolve the qualifierflavor. Since Flavors are a combination of
210 // inheritance and input characteristics, resolve the inherited
211 // characteristics against those provided with the creation. If
212 // there is a superclass the flavor is resolved against that
213 // superclass. If not, it is resolved against the declaration. If
214 // the flavor is disableoverride and tosubclass the resolved
215 // qualifier value must be identical to the original
|
216 a.dunfey 1.56 //----------------------------------------------------------------------
217 // Test for Qualifier found in SuperClass. If found and qualifier
218 // is not overridable.
219 // Abstract (not Overridable and restricted) can be found in subclasses
|
220 kumpf 1.57 // Can have nonabstracts below abstracts. That is function of
221 // nottosubclass Association (notOverridable and tosubclass) can be
222 // found in subclasses but cannot be changed. No non-associatons below
223 // associations. In other words once a class becomes an association,
224 // no subclass can override that definition apparently
225 // Throw exception if DisableOverride and tosubclass and different
226 // value. Gets the source from superclass if qualifier exists or from
227 // declaraction.
228 // If we do not throw the exception, resolve the flavor from the
229 // inheritance point and resolve against current input.
230 // Diableoverride is defined in the CIM Spec to mean that the value
231 // cannot change.
232 // The other characteristics including the flavor can change
233 // apparently. Thus, we need only confirm that the value is the same
234 // (2.2 pp 33). Strange since we would think that override implies
235 // that you cannot override any of the characteristics (value, type,
236 // flavor, etc.) This also leaves the question of NULL or no values.
237 // The implication is that we must move the value from the superclass
238 // or declaration.
|
239 a.dunfey 1.56
240 Uint32 index = inheritedQualifiers.find(q.getName());
241
242 if (index == PEG_NOT_FOUND)
243 { // Qualifier does not exist in superclass
244 /* If from declaration, we can override the default value.
245 However, we need some way to get the value if we have a Null.
|
246 kumpf 1.58 if (!qd.getFlavor().hasFlavor(CIMFlavor::OVERRIDABLE) &&
247 qd.getFlavor().hasFlavor(CIMFlavor::TOSUBCLASS))
|
248 a.dunfey 1.56 {
|
249 kumpf 1.57 //throw BadQualifierOverride(q.getName());
|
250 a.dunfey 1.56 }
|
251 kumpf 1.58 */
|
252 a.dunfey 1.56 // Do not allow change from disable override to enable override.
253 if ((!qd.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
254 && (q.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE)))
|
255 marek 1.60 {
256 PEG_METHOD_EXIT();
|
257 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString ());
|
258 marek 1.60 }
|
259 a.dunfey 1.56
|
260 kumpf 1.57 Resolver::resolveQualifierFlavor(
|
261 marek 1.74 q, CIMFlavor (qd.getFlavor ()));
|
262 a.dunfey 1.56 }
|
263 kumpf 1.57 else // qualifier exists in superclass
|
264 a.dunfey 1.56 { ////// Make Const again
265 CIMQualifier iq = inheritedQualifiers.getQualifier(index);
266 // don't allow change override to notoverride.
267 if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
268 && q.getFlavor ().hasFlavor (CIMFlavor::OVERRIDABLE))
|
269 marek 1.60 {
270 PEG_METHOD_EXIT();
|
271 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString ());
|
272 marek 1.60 }
|
273 a.dunfey 1.56
274 if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
275 && iq.getFlavor ().hasFlavor(CIMFlavor::TOSUBCLASS))
276 {
277 // test if values the same.
278 CIMValue qv = q.getValue();
279 CIMValue iqv = iq.getValue();
|
280 kumpf 1.57 if (!(qv == iqv))
281 {
|
282 marek 1.60 PEG_METHOD_EXIT();
|
283 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString());
|
284 kumpf 1.57 }
|
285 a.dunfey 1.56 }
|
286 kumpf 1.57
287 Resolver::resolveQualifierFlavor(
|
288 marek 1.74 q, CIMFlavor(iq.getFlavor()));
|
289 a.dunfey 1.56 }
290 } // end of this objects qualifier loop
|
291 mike 1.15
292 //--------------------------------------------------------------------------
293 // Propagate qualifiers to subclass or to instance that do not have
294 // already have those qualifiers:
295 //--------------------------------------------------------------------------
|
296 karl 1.25
|
297 kumpf 1.68 if (propagateQualifiers)
|
298 mike 1.15 {
|
299 kumpf 1.68 for (Uint32 i = 0, n = inheritedQualifiers.getCount(); i < n; i++)
300 {
301 CIMQualifier iq = inheritedQualifiers.getQualifier(i);
302
303 if (isInstancePart)
304 {
305 if (!(iq.getFlavor().hasFlavor(CIMFlavor::TOINSTANCE)))
306 continue;
307 }
308 else
309 {
310 if (!(iq.getFlavor().hasFlavor(CIMFlavor::TOSUBCLASS)))
311 continue;
312 }
|
313 a.dunfey 1.56
|
314 kumpf 1.68 // If the qualifiers list does not already contain this qualifier,
315 // then propagate it (and set the propagated flag to true). Else
316 // we keep current value. Note we have already eliminated any
317 // possibility that a nonoverridable qualifier can be in the list.
318 if (find(iq.getName()) != PEG_NOT_FOUND)
|
319 a.dunfey 1.56 continue;
|
320 kumpf 1.68
321 CIMQualifier q = iq.clone();
322 q.setPropagated(true);
323 _qualifiers.insert(0, q);
|
324 a.dunfey 1.56 }
|
325 mike 1.15 }
|
326 marek 1.60 PEG_METHOD_EXIT();
|
327 mike 1.15 }
328
329 void CIMQualifierList::print(PEGASUS_STD(ostream) &os) const
330 {
|
331 mike 1.52 Buffer tmp;
|
332 kumpf 1.65 for (Uint32 i = 0, n = getCount(); i < n; i++)
333 XmlWriter::appendQualifierElement(tmp, _qualifiers[i]);
|
334 mike 1.15 os << tmp.getData() << PEGASUS_STD(endl);
335 }
336
337 Boolean CIMQualifierList::identical(const CIMQualifierList& x) const
338 {
339 Uint32 count = getCount();
340
341 if (count != x.getCount())
|
342 kumpf 1.57 return false;
|
343 mike 1.15
344 for (Uint32 i = 0; i < count; i++)
|
345 mike 1.16 {
|
346 kumpf 1.57 if (!_qualifiers[i].identical(x._qualifiers[i]))
347 return false;
|
348 mike 1.16 }
|
349 mike 1.15
350 return true;
351 }
352
353 void CIMQualifierList::cloneTo(CIMQualifierList& x) const
354 {
|
355 marek 1.63 x._keyIndex = PEGASUS_ORDEREDSET_INDEX_UNKNOWN;
|
356 mike 1.15 x._qualifiers.clear();
|
357 kumpf 1.36 x._qualifiers.reserveCapacity(_qualifiers.size());
|
358 mike 1.15
359 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
|
360 kumpf 1.57 x._qualifiers.append(_qualifiers[i].clone());
|
361 marek 1.63 x._keyIndex = _keyIndex;
362 }
363
364 Boolean CIMQualifierList::isKey() const
365 {
366 static Uint32 _KEY_TAG = generateCIMNameTag(_KEY);
367
368 // Resolve key index if unresolved.
369
370 if (_keyIndex == PEGASUS_ORDEREDSET_INDEX_UNKNOWN)
371 {
372 Uint32 pos = _qualifiers.find(_KEY, _KEY_TAG);
373 ((CIMQualifierList*)this)->_keyIndex = int(pos);
374 }
375
376 // If no key qualifier in list, then return false (default key value).
377
378 if (_keyIndex == PEGASUS_ORDEREDSET_INDEX_NOTFOUND)
379 return false;
380
381 // Obtain value of key qualifier.
382 marek 1.63
383 const CIMValue& value = _qualifiers[_keyIndex]._rep->_value;
384 if (!value.isNull() &&
385 value.getType() == CIMTYPE_BOOLEAN)
386 {
387 Boolean boolVal;
388 value.get(boolVal);
389 return boolVal;
390 }
391
392 return false;
|
393 mike 1.15 }
394
|
395 mike 1.69 CIMQualifierList& CIMQualifierList::addUnchecked(const CIMQualifier& qualifier)
396 {
397 if (qualifier.isUninitialized())
398 throw UninitializedObjectException();
399
400 _qualifiers.append(qualifier);
|
401 kumpf 1.72
402 if (_keyIndex == PEGASUS_ORDEREDSET_INDEX_UNKNOWN &&
|
403 mike 1.69 qualifier._rep->_name == _KEY)
404 _keyIndex = _qualifiers.size()-1;
405
406 return *this;
407 }
408
|
409 mike 1.15 PEGASUS_NAMESPACE_END
|