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