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.13 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <cstdio>
|
33 kumpf 1.19 #include "CIMPropertyRep.h"
|
34 mike 1.13 #include "CIMName.h"
35 #include "CIMScope.h"
|
36 a.dunfey 1.42 #include "DeclContext.h"
|
37 mike 1.51 #include "StrLit.h"
|
38 mike 1.13
|
39 mike 1.17 PEGASUS_USING_STD;
40
|
41 mike 1.13 PEGASUS_NAMESPACE_BEGIN
42
|
43 chip 1.48 CIMPropertyRep::CIMPropertyRep(
44 const CIMPropertyRep& x,
|
45 thilo.boehm 1.69 Boolean propagateQualifiers):
|
46 chip 1.48 _name(x._name),
47 _value(x._value),
48 _arraySize(x._arraySize),
49 _referenceClassName(x._referenceClassName),
50 _classOrigin(x._classOrigin),
|
51 marek 1.60 _propagated(x._propagated),
|
52 thilo.boehm 1.69 _refCounter(1),
|
53 marek 1.60 _ownerCount(0)
|
54 chip 1.48 {
|
55 marek 1.60 // Set the CIM name tag.
56 _nameTag = generateCIMNameTag(_name);
57
|
58 chip 1.48 if (propagateQualifiers)
|
59 kumpf 1.56 x._qualifiers.cloneTo(_qualifiers);
|
60 chip 1.48 }
61
|
62 mike 1.13 CIMPropertyRep::CIMPropertyRep(
|
63 kumpf 1.30 const CIMName& name,
|
64 mike 1.13 const CIMValue& value,
65 Uint32 arraySize,
|
66 kumpf 1.30 const CIMName& referenceClassName,
67 const CIMName& classOrigin,
|
68 chip 1.48 Boolean propagated)
|
69 mike 1.17 :
|
70 mike 1.13 _name(name), _value(value), _arraySize(arraySize),
71 _referenceClassName(referenceClassName), _classOrigin(classOrigin),
|
72 thilo.boehm 1.69 _propagated(propagated), _refCounter(1), _ownerCount(0)
|
73 mike 1.13 {
|
74 chip 1.48 // ensure name is not null
|
75 kumpf 1.57 if (name.isNull())
|
76 chip 1.48 {
77 throw UninitializedObjectException();
78 }
79
|
80 marek 1.60 // Set the CIM name tag.
81 _nameTag = generateCIMNameTag(_name);
82
|
83 kumpf 1.56 if ((arraySize != 0) &&
84 (!value.isArray() || value.getArraySize() != arraySize))
|
85 chip 1.48 {
|
86 kumpf 1.38 throw TypeMismatchException();
|
87 chip 1.48 }
|
88 mike 1.13
|
89 kumpf 1.49 // A CIM Property may not be of reference array type
90 if (value.isArray() && (value.getType() == CIMTYPE_REFERENCE))
91 {
92 throw TypeMismatchException();
93 }
94
|
95 chip 1.48 // if referenceClassName exists, must be CIMType REFERENCE.
|
96 kumpf 1.30 if (!referenceClassName.isNull())
|
97 mike 1.13 {
|
98 kumpf 1.30 if (_value.getType() != CIMTYPE_REFERENCE)
|
99 chip 1.48 {
|
100 kumpf 1.38 throw TypeMismatchException();
|
101 chip 1.48 }
|
102 kumpf 1.30 }
|
103 kumpf 1.41
104 // Can a property be of reference type with a null referenceClassName?
105 // The DMTF says yes if it is a property of an instance; no if it is a
106 // property of a class. We'll allow it here, but check in the CIMClass
107 // addProperty() method.
|
108 mike 1.13 }
109
|
110 kumpf 1.30 void CIMPropertyRep::setName(const CIMName& name)
|
111 mike 1.13 {
|
112 chip 1.48 // ensure name is not null
|
113 kumpf 1.57 if (name.isNull())
|
114 chip 1.48 {
115 throw UninitializedObjectException();
116 }
117
|
118 marek 1.60 if (_ownerCount != 0 && _name != name)
119 {
120 MessageLoaderParms parms(
121 "Common.CIMPropertyRep.CONTAINED_PROPERTY_NAMECHANGEDEXCEPTION",
122 "Attempted to change the name of a property"
123 " already in a container.");
124 throw Exception(parms);
125 }
126
|
127 mike 1.13 _name = name;
|
128 marek 1.60
129 // Set the CIM name tag.
130 _nameTag = generateCIMNameTag(_name);
|
131 mike 1.13 }
132
133 void CIMPropertyRep::resolve(
134 DeclContext* declContext,
|
135 kumpf 1.30 const CIMNamespaceName& nameSpace,
|
136 mike 1.13 Boolean isInstancePart,
|
137 mike 1.17 const CIMConstProperty& inheritedProperty,
138 Boolean propagateQualifiers)
|
139 mike 1.13 {
|
140 kumpf 1.32 PEGASUS_ASSERT(!inheritedProperty.isUninitialized());
|
141 mike 1.13
142 // Check the type:
143
144 if (!inheritedProperty.getValue().typeCompatible(_value))
|
145 dave.sudlik 1.47 {
146 if (!(
147 (inheritedProperty.getValue().getType() == CIMTYPE_OBJECT) &&
148 (_value.getType() == CIMTYPE_STRING) &&
|
149 kumpf 1.73 (_qualifiers.find(PEGASUS_QUALIFIERNAME_EMBEDDEDOBJECT)
|
150 thilo.boehm 1.67 != PEG_NOT_FOUND) &&
|
151 dave.sudlik 1.47 (inheritedProperty.getValue().isArray() == _value.isArray())
|
152 a.dunfey 1.53 ) &&
153 !(
154 (inheritedProperty.getValue().getType() == CIMTYPE_INSTANCE) &&
155 (_value.getType() == CIMTYPE_STRING) &&
|
156 kumpf 1.73 (_qualifiers.find(PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE)
|
157 thilo.boehm 1.67 != PEG_NOT_FOUND) &&
|
158 a.dunfey 1.53 (inheritedProperty.getValue().isArray() == _value.isArray())
|
159 dave.sudlik 1.47 ))
160 {
161 throw TypeMismatchException();
162 }
163 }
|
164 mike 1.13
165 // Validate the qualifiers of the property (according to
166 // superClass's property with the same name). This method
167 // will throw an exception if the validation fails.
168
|
169 kumpf 1.35 CIMScope scope = CIMScope::PROPERTY;
|
170 mike 1.13
|
171 kumpf 1.29 if (_value.getType() == CIMTYPE_REFERENCE)
|
172 a.dunfey 1.53 scope = CIMScope::REFERENCE;
|
173 mike 1.13
|
174 a.dunfey 1.42 // Test the reference class name against the inherited property
|
175 kumpf 1.73 if (_value.getType() == CIMTYPE_REFERENCE ||
|
176 dmitry.mikulin 1.61 _value.getType() == CIMTYPE_INSTANCE)
|
177 a.dunfey 1.53 {
178 CIMName inheritedClassName;
179 Array<CIMName> classNames;
|
180 a.dunfey 1.55
|
181 dmitry.mikulin 1.61 if (_value.getType() == CIMTYPE_INSTANCE)
|
182 a.dunfey 1.43 {
|
183 thilo.boehm 1.67 Uint32 pos = inheritedProperty.findQualifier(
184 PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE);
|
185 kumpf 1.57 if (pos != PEG_NOT_FOUND)
|
186 a.dunfey 1.43 {
|
187 a.dunfey 1.53 String qualStr;
188 inheritedProperty.getQualifier(pos).getValue().get(qualStr);
189 inheritedClassName = qualStr;
190 }
191
|
192 kumpf 1.57 if (_value.isArray())
|
193 a.dunfey 1.53 {
194 Array<CIMInstance> embeddedInstances;
195 _value.get(embeddedInstances);
|
196 kumpf 1.57 for (Uint32 i = 0, n = embeddedInstances.size(); i < n; ++i)
|
197 a.dunfey 1.43 {
|
198 a.dunfey 1.53 classNames.append(embeddedInstances[i].getClassName());
|
199 a.dunfey 1.43 }
|
200 a.dunfey 1.53 }
201 else
202 {
203 CIMInstance embeddedInst;
204 _value.get(embeddedInst);
205 classNames.append(embeddedInst.getClassName());
|
206 a.dunfey 1.43 }
207 }
|
208 a.dunfey 1.53 else
|
209 a.dunfey 1.43 {
|
210 a.dunfey 1.55 CIMName referenceClass;
211 if (_referenceClassName.isNull())
212 {
|
213 kumpf 1.56 CIMObjectPath reference;
|
214 a.dunfey 1.55 _value.get(reference);
215 referenceClass = reference.getClassName();
216 }
217 else
218 {
219 referenceClass = _referenceClassName;
220 }
221
222 inheritedClassName = inheritedProperty.getReferenceClassName();
223 classNames.append(referenceClass);
|
224 a.dunfey 1.43 }
|
225 a.dunfey 1.42
|
226 a.dunfey 1.53 // This algorithm is friendly to arrays of embedded instances. It
227 // remembers the class names that are found to be subclasses of the
228 // inherited class name retrieved from the inherited property. This
229 // ensures that any branch in the inheritance hierarchy will only be
230 // traversed once. This provides significant optimization given that
231 // most elements of an array of embedded instances will probably be of
232 // very closely related types.
233 Array<CIMName> successTree;
234 successTree.append(inheritedClassName);
|
235 kumpf 1.57 for (Uint32 i = 0, n = classNames.size(); i < n; ++i)
|
236 a.dunfey 1.43 {
|
237 a.dunfey 1.53 Array<CIMName> traversalHistory;
238 CIMName currentName = classNames[i];
239 Boolean found = false;
|
240 kumpf 1.57 while (!found && !currentName.isNull())
|
241 a.dunfey 1.43 {
|
242 kumpf 1.57 for (Uint32 j = 0, m = successTree.size(); j < m; ++j)
|
243 a.dunfey 1.43 {
|
244 kumpf 1.57 if (currentName == successTree[j])
|
245 a.dunfey 1.53 {
246 found = true;
247 break;
248 }
|
249 a.dunfey 1.43 }
250
|
251 kumpf 1.57 if (!found)
|
252 a.dunfey 1.53 {
253 traversalHistory.append(currentName);
254 CIMClass currentClass = declContext->lookupClass(
255 nameSpace, currentName);
|
256 kumpf 1.57 if (currentClass.isUninitialized())
|
257 a.dunfey 1.53 {
258 throw PEGASUS_CIM_EXCEPTION(
|
259 kumpf 1.66 CIM_ERR_INVALID_PARAMETER, currentName.getString());
|
260 a.dunfey 1.53 }
261 currentName = currentClass.getSuperClassName();
262 }
|
263 a.dunfey 1.43 }
|
264 a.dunfey 1.53
|
265 kumpf 1.57 if (!found)
|
266 a.dunfey 1.53 {
267 throw TypeMismatchException();
268 }
269
270 successTree.appendArray(traversalHistory);
|
271 a.dunfey 1.43 }
|
272 kumpf 1.41 }
273
|
274 mike 1.13 _qualifiers.resolve(
|
275 a.dunfey 1.53 declContext, nameSpace, scope, isInstancePart,
276 inheritedProperty._rep->_qualifiers, propagateQualifiers);
|
277 mike 1.13
278 _classOrigin = inheritedProperty.getClassOrigin();
279 }
280
281 void CIMPropertyRep::resolve(
282 DeclContext* declContext,
|
283 kumpf 1.30 const CIMNamespaceName& nameSpace,
|
284 mike 1.17 Boolean isInstancePart,
|
285 kumpf 1.28 Boolean propagateQualifiers)
|
286 mike 1.13 {
287 CIMQualifierList dummy;
288
|
289 kumpf 1.35 CIMScope scope = CIMScope::PROPERTY;
|
290 mike 1.13
|
291 kumpf 1.29 if (_value.getType() == CIMTYPE_REFERENCE)
|
292 kumpf 1.72 {
|
293 a.dunfey 1.53 scope = CIMScope::REFERENCE;
|
294 mike 1.13
|
295 kumpf 1.72 // Validate that the reference class exists.
296
297 CIMName referenceClassName;
298 if (_referenceClassName.isNull())
299 {
300 CIMObjectPath reference;
301 _value.get(reference);
302 referenceClassName = reference.getClassName();
303 }
304 else
305 {
306 referenceClassName = _referenceClassName;
307 }
308
309 CIMClass referenceClass = declContext->lookupClass(
310 nameSpace, referenceClassName);
311 if (referenceClass.isUninitialized())
312 {
313 throw PEGASUS_CIM_EXCEPTION(
314 CIM_ERR_INVALID_PARAMETER, referenceClassName.getString());
315 }
316 kumpf 1.72 }
317
|
318 mike 1.13 _qualifiers.resolve(
|
319 a.dunfey 1.53 declContext,
320 nameSpace,
321 scope,
322 isInstancePart,
323 dummy,
324 propagateQualifiers);
|
325 mike 1.13 }
326
327 Boolean CIMPropertyRep::identical(const CIMPropertyRep* x) const
328 {
|
329 kumpf 1.58 // If the pointers are the same, the objects must be identical
330 if (this == x)
331 {
332 return true;
333 }
334
|
335 kumpf 1.39 if (!_name.equal (x->_name))
|
336 kumpf 1.56 return false;
|
337 mike 1.13
338 if (_value != x->_value)
|
339 kumpf 1.56 return false;
|
340 mike 1.13
|
341 kumpf 1.39 if (!_referenceClassName.equal (x->_referenceClassName))
|
342 kumpf 1.56 return false;
|
343 mike 1.13
344 if (!_qualifiers.identical(x->_qualifiers))
|
345 kumpf 1.56 return false;
|
346 mike 1.13
|
347 kumpf 1.39 if (!_classOrigin.equal (x->_classOrigin))
|
348 kumpf 1.56 return false;
|
349 mike 1.13
350 if (_propagated != x->_propagated)
|
351 kumpf 1.56 return false;
|
352 mike 1.13
353 return true;
354 }
355
356 void CIMPropertyRep::setValue(const CIMValue& value)
357 {
358 // CIMType of value is immutable:
359
360 if (!value.typeCompatible(_value))
|
361 kumpf 1.56 throw TypeMismatchException();
|
362 mike 1.13
363 if (_arraySize && _arraySize != value.getArraySize())
|
364 kumpf 1.56 throw TypeMismatchException();
|
365 mike 1.13
|
366 kumpf 1.49 // A CIM Property may not be of reference array type
367 if (value.isArray() && (value.getType() == CIMTYPE_REFERENCE))
368 {
369 throw TypeMismatchException();
370 }
371
|
372 mike 1.13 _value = value;
373 }
374
375 PEGASUS_NAMESPACE_END
|