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
|