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 "Indentor.h"
40 #include "XmlWriter.h"
|
41 kumpf 1.34 #include "MofWriter.h"
|
42 karl 1.29 #include <Pegasus/Common/Tracer.h>
|
43 kumpf 1.59 #include <Pegasus/Common/MessageLoader.h>
|
44 mike 1.53 #include "StrLit.h"
|
45 mike 1.54 #include "ArrayIterator.h"
|
46 mike 1.15
47 PEGASUS_NAMESPACE_BEGIN
|
48 karl 1.18 PEGASUS_USING_STD;
|
49 mike 1.15
50 CIMQualifierList::CIMQualifierList()
51 {
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
75 return *this;
76 }
77 //ATTN: Why do we not do the outofbounds check here. KS 18 May 2k
|
78 kumpf 1.45 CIMQualifier& CIMQualifierList::getQualifier(Uint32 index)
|
79 mike 1.15 {
|
80 kumpf 1.45 return _qualifiers[index];
|
81 mike 1.15 }
82
83 //ATTN: added ks 18 may 2001. Should we have outofbounds?
|
84 kumpf 1.45 void CIMQualifierList::removeQualifier(Uint32 index)
|
85 mike 1.15 {
|
86 kumpf 1.45 _qualifiers.remove(index);
|
87 mike 1.15 }
88
|
89 kumpf 1.39 Uint32 CIMQualifierList::find(const CIMName& name) const
|
90 mike 1.15 {
|
91 mike 1.54 ConstArrayIterator<CIMQualifier> qualifiers(_qualifiers);
92
93 for (Uint32 i = 0, n = qualifiers.size(); i < n; i++)
|
94 mike 1.15 {
|
95 kumpf 1.57 if (name.equal(qualifiers[i].getName()))
96 return i;
|
97 mike 1.15 }
98
99 return PEG_NOT_FOUND;
100 }
|
101 kumpf 1.39 Boolean CIMQualifierList::isTrue(const CIMName& name) const
|
102 karl 1.28 {
|
103 kumpf 1.45 Uint32 index = find(name);
|
104 karl 1.28
|
105 kumpf 1.45 if (index == PEG_NOT_FOUND)
|
106 kumpf 1.57 return false;
|
107 karl 1.28
108 Boolean flag;
|
109 kumpf 1.45 const CIMValue& value = getQualifier(index).getValue();
|
110 karl 1.28
|
111 kumpf 1.38 if (value.getType() != CIMTYPE_BOOLEAN)
|
112 kumpf 1.57 return false;
|
113 karl 1.28
114 value.get(flag);
115 return flag;
116 }
|
117 mike 1.15
|
118 kumpf 1.39 Uint32 CIMQualifierList::findReverse(const CIMName& name) const
|
119 mike 1.15 {
120 for (Uint32 i = _qualifiers.size(); i; --i)
121 {
|
122 kumpf 1.57 if (name.equal(_qualifiers[i-1].getName()))
123 return i - 1;
|
124 mike 1.15 }
125
126 return PEG_NOT_FOUND;
127 }
128
129 void CIMQualifierList::resolve(
130 DeclContext* declContext,
|
131 kumpf 1.46 const CIMNamespaceName & nameSpace,
|
132 a.dunfey 1.56 CIMScope scope, // Scope of the entity being resolved.
|
133 mike 1.15 Boolean isInstancePart,
|
134 mike 1.23 CIMQualifierList& inheritedQualifiers,
|
135 a.dunfey 1.56 Boolean propagateQualifiers) // Apparently not used ks 24 mar 2002
|
136 mike 1.15 {
|
137 karl 1.29 PEG_METHOD_ENTER(TRC_OBJECTRESOLUTION, "CIMQualifierList::resolve()");
|
138 mike 1.15 // For each qualifier in the qualifiers array, the following
139 // is checked:
140 //
141 // 1. Whether it is declared (can be obtained from the declContext).
142 //
143 // 2. Whether it has the same type as the declaration.
144 //
|
145 a.dunfey 1.56 // 3. Whether the qualifier is valid for the given scope.
|
146 mike 1.15 //
|
147 a.dunfey 1.56 // 4. Whether the qualifier can be overriden (the flavor is
148 // ENABLEOVERRIDE on the corresponding reference qualifier).
|
149 mike 1.15 //
|
150 a.dunfey 1.56 // 5. Whether the qualifier should be propagated to the subclass.
|
151 mike 1.15 //
152 // If the qualifier should be overriden, then it is injected into the
153 // qualifiers array (from the inheritedQualifiers array).
154
155 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
156 {
|
157 a.dunfey 1.56 CIMQualifier q = _qualifiers[i];
158 //----------------------------------------------------------------------
159 // 1. Check to see if it's declared.
160 //----------------------------------------------------------------------
161 // set this back to CIMConstQualifierDecl
162 CIMQualifierDecl qd = declContext->lookupQualifierDecl(
163 nameSpace, q.getName());
|
164 kumpf 1.57
|
165 a.dunfey 1.56 if (qd.isUninitialized())
|
166 marek 1.59.4.1 {
167 PEG_METHOD_EXIT();
|
168 a.dunfey 1.56 throw UndeclaredQualifier(q.getName().getString ());
|
169 marek 1.59.4.1 }
|
170 kumpf 1.57
|
171 a.dunfey 1.56 //----------------------------------------------------------------------
172 // 2. Check the type and isArray. Must be the same:
173 //----------------------------------------------------------------------
|
174 kumpf 1.57
|
175 a.dunfey 1.56 if (!(q.getType() == qd.getType() && q.isArray() == qd.isArray()))
|
176 marek 1.59.4.1 {
177 PEG_METHOD_EXIT();
|
178 a.dunfey 1.56 throw BadQualifierType(q.getName().getString ());
|
179 marek 1.59.4.1 }
|
180 kumpf 1.57
|
181 a.dunfey 1.56 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
182 //----------------------------------------------------------------------
183 // 3. If the qualifier is the EmbeddedInstance qualifier, then check
184 // that the class specified by the qualifier exists in the namespace.
185 //----------------------------------------------------------------------
|
186 kumpf 1.59 if (q.getName().equal(CIMName("EmbeddedInstance")))
|
187 a.dunfey 1.56 {
188 String className;
189 q.getValue().get(className);
190 CIMClass classDef = declContext->lookupClass(nameSpace,
191 CIMName(className));
|
192 kumpf 1.59 if (classDef.isUninitialized())
|
193 a.dunfey 1.56 {
194 String embeddedInstType("EmbeddedInstance(\"");
195 embeddedInstType = embeddedInstType + className + "\")";
|
196 marek 1.59.4.1 PEG_METHOD_EXIT();
|
197 a.dunfey 1.56 throw BadQualifierType(embeddedInstType);
198 }
199 }
200 #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
201
202 //----------------------------------------------------------------------
203 // 4. Check the scope: Must be legal for this qualifier
204 //----------------------------------------------------------------------
|
205 kumpf 1.57 // ATTN: These lines throw a bogus exception if the qualifier has
206 // a valid scope (such as Scope::ASSOCIATION) which is not Scope::CLASS
207 // ks Mar 2002. Reinstalled 23 March 2002 to test.
|
208 a.dunfey 1.56
209 if (!(qd.getScope().hasScope (scope)))
|
210 marek 1.59.4.1 {
211 PEG_METHOD_EXIT();
|
212 a.dunfey 1.56 throw BadQualifierScope
213 (qd.getName().getString (), scope.toString ());
|
214 marek 1.59.4.1 }
|
215 kumpf 1.57
|
216 a.dunfey 1.56 //----------------------------------------------------------------------
|
217 kumpf 1.57 // Resolve the qualifierflavor. Since Flavors are a combination of
218 // inheritance and input characteristics, resolve the inherited
219 // characteristics against those provided with the creation. If
220 // there is a superclass the flavor is resolved against that
221 // superclass. If not, it is resolved against the declaration. If
222 // the flavor is disableoverride and tosubclass the resolved
223 // qualifier value must be identical to the original
|
224 a.dunfey 1.56 //----------------------------------------------------------------------
225 // Test for Qualifier found in SuperClass. If found and qualifier
226 // is not overridable.
227 // Abstract (not Overridable and restricted) can be found in subclasses
|
228 kumpf 1.57 // Can have nonabstracts below abstracts. That is function of
229 // nottosubclass Association (notOverridable and tosubclass) can be
230 // found in subclasses but cannot be changed. No non-associatons below
231 // associations. In other words once a class becomes an association,
232 // no subclass can override that definition apparently
233 // Throw exception if DisableOverride and tosubclass and different
234 // value. Gets the source from superclass if qualifier exists or from
235 // declaraction.
236 // If we do not throw the exception, resolve the flavor from the
237 // inheritance point and resolve against current input.
238 // Diableoverride is defined in the CIM Spec to mean that the value
239 // cannot change.
240 // The other characteristics including the flavor can change
241 // apparently. Thus, we need only confirm that the value is the same
242 // (2.2 pp 33). Strange since we would think that override implies
243 // that you cannot override any of the characteristics (value, type,
244 // flavor, etc.) This also leaves the question of NULL or no values.
245 // The implication is that we must move the value from the superclass
246 // or declaration.
|
247 a.dunfey 1.56
248 Uint32 index = inheritedQualifiers.find(q.getName());
249
250 if (index == PEG_NOT_FOUND)
251 { // Qualifier does not exist in superclass
252 /* If from declaration, we can override the default value.
253 However, we need some way to get the value if we have a Null.
|
254 kumpf 1.58 if (!qd.getFlavor().hasFlavor(CIMFlavor::OVERRIDABLE) &&
255 qd.getFlavor().hasFlavor(CIMFlavor::TOSUBCLASS))
|
256 a.dunfey 1.56 {
|
257 kumpf 1.57 //throw BadQualifierOverride(q.getName());
|
258 a.dunfey 1.56 }
|
259 kumpf 1.58 */
|
260 a.dunfey 1.56 // Do not allow change from disable override to enable override.
261 if ((!qd.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
262 && (q.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE)))
|
263 marek 1.59.4.1 {
264 PEG_METHOD_EXIT();
|
265 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString ());
|
266 marek 1.59.4.1 }
|
267 a.dunfey 1.56
|
268 kumpf 1.57 Resolver::resolveQualifierFlavor(
269 q, CIMFlavor (qd.getFlavor ()), false);
|
270 a.dunfey 1.56 }
|
271 kumpf 1.57 else // qualifier exists in superclass
|
272 a.dunfey 1.56 { ////// Make Const again
273 CIMQualifier iq = inheritedQualifiers.getQualifier(index);
274 // don't allow change override to notoverride.
275 if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
276 && q.getFlavor ().hasFlavor (CIMFlavor::OVERRIDABLE))
|
277 marek 1.59.4.1 {
278 PEG_METHOD_EXIT();
|
279 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString ());
|
280 marek 1.59.4.1 }
|
281 a.dunfey 1.56
282 if (!(iq.getFlavor ().hasFlavor(CIMFlavor::OVERRIDABLE))
283 && iq.getFlavor ().hasFlavor(CIMFlavor::TOSUBCLASS))
284 {
285 // test if values the same.
286 CIMValue qv = q.getValue();
287 CIMValue iqv = iq.getValue();
|
288 kumpf 1.57 if (!(qv == iqv))
289 {
|
290 marek 1.59.4.1 PEG_METHOD_EXIT();
|
291 a.dunfey 1.56 throw BadQualifierOverride(q.getName().getString());
|
292 kumpf 1.57 }
|
293 a.dunfey 1.56 }
|
294 kumpf 1.57
295 Resolver::resolveQualifierFlavor(
296 q, CIMFlavor(iq.getFlavor()), true);
|
297 a.dunfey 1.56 }
298 } // end of this objects qualifier loop
|
299 mike 1.15
300 //--------------------------------------------------------------------------
301 // Propagate qualifiers to subclass or to instance that do not have
302 // already have those qualifiers:
303 //--------------------------------------------------------------------------
|
304 karl 1.25
|
305 mike 1.15 for (Uint32 i = 0, n = inheritedQualifiers.getCount(); i < n; i++)
306 {
|
307 a.dunfey 1.56 CIMQualifier iq = inheritedQualifiers.getQualifier(i);
308
309 if (isInstancePart)
310 {
311 if (!(iq.getFlavor ().hasFlavor
312 (CIMFlavor::TOINSTANCE)))
313 continue;
314 }
315 else
316 {
317 if (!(iq.getFlavor ().hasFlavor
318 (CIMFlavor::TOSUBCLASS)))
319 continue;
320 }
321
322 // If the qualifiers list does not already contain this qualifier,
|
323 kumpf 1.57 // then propagate it (and set the propagated flag to true). Else we
324 // keep current value. Note we have already eliminated any possibity
325 // that a nonoverridable qualifier can be in the list.
|
326 a.dunfey 1.56 // Note that there is no exists() function ATTN:KS 25 Mar 2002
|
327 kumpf 1.59 if (find(iq.getName()) != PEG_NOT_FOUND)
|
328 a.dunfey 1.56 continue;
329
330 CIMQualifier q = iq.clone();
331 q.setPropagated(true);
332 _qualifiers.prepend(q);
|
333 mike 1.15 }
|
334 marek 1.59.4.1 PEG_METHOD_EXIT();
|
335 mike 1.15 }
336
|
337 mike 1.52 void CIMQualifierList::toXml(Buffer& out) const
|
338 mike 1.15 {
339 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
|
340 kumpf 1.57 XmlWriter::appendQualifierElement(out, _qualifiers[i]);
|
341 mike 1.15 }
342
|
343 mike 1.17 /** toMof - Generates MOF output for a list of CIM Qualifiers.
344 The qualifiers may be class, property, parameter, etc.
345 The BNF for this is:
346 <pre>
347 qualifierList = "[" qualifier *( "," qualifier ) "]"
348 </pre>
349 Produces qualifiers as a string on without nl.
350 */
|
351 mike 1.52 void CIMQualifierList::toMof(Buffer& out) const
|
352 mike 1.17 {
353 // if no qualifiers, return
354 if (_qualifiers.size() == 0)
|
355 kumpf 1.57 return;
|
356 mike 1.17
357 // Qualifier leading bracket.
|
358 mike 1.53 out.append('[');
|
359 mike 1.17
360 // Loop to list qualifiers
361 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
362 {
|
363 kumpf 1.57 // if second or greater, add comma separator
364 if (i > 0)
365 out << STRLIT(", \n");
366 MofWriter::appendQualifierElement(out, _qualifiers[i]);
|
367 mike 1.17 }
|
368 kumpf 1.57
|
369 mike 1.17 // Terminating bracket
|
370 mike 1.53 out.append(']');
|
371 mike 1.17 }
372
373
|
374 mike 1.15 void CIMQualifierList::print(PEGASUS_STD(ostream) &os) const
375 {
|
376 mike 1.52 Buffer tmp;
|
377 mike 1.15 toXml(tmp);
378 tmp.append('\0');
379 os << tmp.getData() << PEGASUS_STD(endl);
380 }
381
382 Boolean CIMQualifierList::identical(const CIMQualifierList& x) const
383 {
384 Uint32 count = getCount();
385
386 if (count != x.getCount())
|
387 kumpf 1.57 return false;
|
388 mike 1.15
389 for (Uint32 i = 0; i < count; i++)
|
390 mike 1.16 {
|
391 kumpf 1.57 if (!_qualifiers[i].identical(x._qualifiers[i]))
392 return false;
|
393 mike 1.16 }
|
394 mike 1.15
395 return true;
396 }
397
398 void CIMQualifierList::cloneTo(CIMQualifierList& x) const
399 {
400 x._qualifiers.clear();
|
401 kumpf 1.36 x._qualifiers.reserveCapacity(_qualifiers.size());
|
402 mike 1.15
403 for (Uint32 i = 0, n = _qualifiers.size(); i < n; i++)
|
404 kumpf 1.57 x._qualifiers.append(_qualifiers[i].clone());
|
405 mike 1.15 }
406
407 PEGASUS_NAMESPACE_END
|