1 mike 1.1.2.1 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // 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 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // 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 // 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 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.1.2.1 // 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 // 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 // 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 <cstdarg>
35 #include <Pegasus/Common/Resolver.h>
36 #include "MemoryResidentInstanceRepository.h"
37 #include "MetaRepository.h"
38 #include "MetaRepositoryDeclContext.h"
39 #include "Filtering.h"
40
41 PEGASUS_NAMESPACE_BEGIN
42
43 mike 1.1.2.1 #define PEGASUS_ARRAY_T NamespaceInstancePair
44 # include <Pegasus/Common/ArrayImpl.h>
45 #undef PEGASUS_ARRAY_T
46
47 #define TRACE printf("TRACE: %s(%d): %s\n", __FILE__, __LINE__, __FUNCTION__)
48
49 //==============================================================================
50 //
51 // Local routines:
52 //
53 //==============================================================================
54
55 PEGASUS_FORMAT(2, 3)
56 static void _throw(CIMStatusCode code, const char* format, ...)
57 {
58 char buffer[4096];
59
60 va_list ap;
61 va_start(ap, format);
62 vsprintf(buffer, format, ap);
63 va_end(ap);
64 mike 1.1.2.1 throw CIMException(code, buffer);
65 }
66
67 class Str
68 {
69 public:
70 Str(const String& s) : _cstr(s.getCString()) { }
71 Str(const CIMName& n) : _cstr(n.getString().getCString()) { }
72 Str(const CIMNamespaceName& n) : _cstr(n.getString().getCString()) { }
73 Str(const Exception& e) : _cstr(e.getMessage().getCString()) { }
74 Str(const CIMDateTime& x) : _cstr(x.toString().getCString()) { }
75 Str(const CIMObjectPath& x) : _cstr(x.toString().getCString()) { }
76 const char* operator*() const { return (const char*)_cstr; }
77 operator const char*() const { return (const char*)_cstr; }
78 private:
79 CString _cstr;
80 };
81
82 static bool _contains(const CIMPropertyList& propertyList, const CIMName& name)
83 {
84 for (Uint32 i = 0; i < propertyList.size(); i++)
85 mike 1.1.2.1 {
86 if (propertyList[i] == name)
87 return true;
88 }
89
90 return false;
91 }
92
93 static void _applyModifiedInstance(
94 const MetaClass* mc,
95 const CIMInstance& modifiedInstance_,
96 const CIMPropertyList& propertyList,
97 CIMInstance& resultInstance)
98 {
99 CIMInstance& modifiedInstance = *((CIMInstance*)&modifiedInstance_);
100
101 for (Uint32 i = 0; i < modifiedInstance.getPropertyCount(); i++)
102 {
103 CIMProperty cp = modifiedInstance.getProperty(i);
104 Uint32 pos = resultInstance.findProperty(cp.getName());
105
106 mike 1.1.2.1 if (propertyList.isNull() || _contains(propertyList, cp.getName()))
107 {
108 // Reject attempts to add properties not in class:
109
110 const MetaFeature* mf = FindFeature(
111 mc, *Str(cp.getName()), META_FLAG_PROPERTY|META_FLAG_REFERENCE);
112
113 if (!mf)
114 {
115 _throw(CIM_ERR_NOT_FOUND,
116 "modifyInstance() failed: unknown property: %s",
117 *Str(cp.getName()));
118 }
119
120 // Reject attempts to modify key properties:
121
122 if (mf->flags & META_FLAG_KEY)
123 {
124 _throw(CIM_ERR_FAILED,
125 "modifyInstance() failed to modify key property: %s",
126 *Str(cp.getName()));
127 mike 1.1.2.1 }
128
129 // Add or replace property in result instance:
130
131 if (pos != PEG_NOT_FOUND)
132 resultInstance.removeProperty(pos);
133
134 resultInstance.addProperty(cp);
135 }
136 }
137 }
138
139 static void _print(const CIMInstance& ci)
140 {
141 CIMObject co(ci);
142
143 std::cout << co.toString() << std::endl;
144 }
145
146 //==============================================================================
147 //
148 mike 1.1.2.1 // class MemoryResidentInstanceRepository
149 //
150 //==============================================================================
151
152 MemoryResidentInstanceRepository::MemoryResidentInstanceRepository()
153 {
154 }
155
156 MemoryResidentInstanceRepository::~MemoryResidentInstanceRepository()
157 {
158 }
159
160 CIMInstance MemoryResidentInstanceRepository::getInstance(
161 const CIMNamespaceName& nameSpace,
162 const CIMObjectPath& instanceName,
163 Boolean localOnly,
164 Boolean includeQualifiers,
165 Boolean includeClassOrigin,
166 const CIMPropertyList& propertyList)
167 {
168 TRACE;
169 mike 1.1.2.1
170 Uint32 pos = _findInstance(nameSpace, instanceName);
171
172 if (pos == PEG_NOT_FOUND)
173 _throw(CIM_ERR_NOT_FOUND, "%s", *Str(instanceName));
174
175 CIMInstance cimInstance = _rep[pos].second.clone();
176
177 Filtering::filterInstance(
178 cimInstance,
179 localOnly,
180 includeQualifiers,
181 includeClassOrigin,
182 propertyList);
183
184 return cimInstance;
185 }
186
187 void MemoryResidentInstanceRepository::deleteInstance(
188 const CIMNamespaceName& nameSpace,
189 const CIMObjectPath& instanceName)
190 mike 1.1.2.1 {
191 TRACE;
192
193 Uint32 pos = _findInstance(nameSpace, instanceName);
194
195 if (pos == PEG_NOT_FOUND)
196 _throw(CIM_ERR_NOT_FOUND, "%s", *Str(instanceName));
197
198 _rep.remove(pos);
199 }
200
201 CIMObjectPath MemoryResidentInstanceRepository::createInstance(
202 const CIMNamespaceName& nameSpace,
203 const CIMInstance& newInstance)
204 {
205 TRACE;
206
207 // Resolve the instance first:
208
209 CIMInstance ci(newInstance.clone());
210 CIMConstClass cc;
211 mike 1.1.2.1 MetaRepositoryDeclContext context;
212 Resolver::resolveInstance(ci, &context, nameSpace, cc, false);
213 CIMObjectPath cop = ci.buildPath(cc);
214
215 ci.setPath(cop);
216
217 // Reject if an instance with this name already exists:
218
219 if (_findInstance(nameSpace, cop) != PEG_NOT_FOUND)
220 _throw(CIM_ERR_ALREADY_EXISTS, "%s", *Str(cop));
221
222 // Add instance to array:
223
224 _rep.append(NamespaceInstancePair(nameSpace, ci));
225
226 return cop;
227 }
228
229 void MemoryResidentInstanceRepository::modifyInstance(
230 const CIMNamespaceName& nameSpace,
231 const CIMInstance& modifiedInstance,
232 mike 1.1.2.1 Boolean includeQualifiers,
233 const CIMPropertyList& propertyList)
234 {
235 TRACE;
236
237 const CIMObjectPath& cop = modifiedInstance.getPath();
238 CIMName className = cop.getClassName();
239
240 // Get the meta class for this instance.
241
242 const MetaClass* mc = MetaRepository::findMetaClass(
243 *Str(nameSpace), *Str(className));
244
245 if (!mc)
246 {
247 _throw(CIM_ERR_FAILED,
248 "modifyInstance() failed: unknown class: %s:%s",
249 *Str(nameSpace), *Str(className));
250 }
251
252 // Get original instance to be modified:
253 mike 1.1.2.1
254 Uint32 pos = _findInstance(nameSpace, cop);
255
256 if (pos == PEG_NOT_FOUND)
257 {
258 _throw(CIM_ERR_NOT_FOUND, "modified() failed: unknown instance: %s",
259 *Str(cop.toString()));
260 }
261
262 CIMInstance resultInstance = _rep[pos].second.clone();
263
264 // Apply features of modifiedInstance to result instance.
265
266 _applyModifiedInstance(mc, modifiedInstance, propertyList, resultInstance);
267
268 // Resolve the instance.
269
270 CIMConstClass cc;
271 MetaRepositoryDeclContext context;
272 Resolver::resolveInstance(resultInstance, &context, nameSpace, cc, false);
273
274 mike 1.1.2.1 // Replace original instance.
275
276 _rep[pos].second = resultInstance;
277 }
278
279 Array<CIMInstance>
280 MemoryResidentInstanceRepository::enumerateInstancesForSubtree(
281 const CIMNamespaceName& nameSpace,
282 const CIMName& className,
283 Boolean deepInheritance,
284 Boolean localOnly,
285 Boolean includeQualifiers,
286 Boolean includeClassOrigin,
287 const CIMPropertyList& propertyList)
288 {
289 TRACE;
290
291 // Form array of classnames for this class and descendent classes:
292
293 Array<CIMName> classNames;
294 classNames.append(className);
295 mike 1.1.2.1 MetaRepository::getSubClassNames(nameSpace, className, true, classNames);
296
297 // Get all instances for this class and all descendent classes
298
299 Array<CIMInstance> result;
300
301 for (Uint32 i = 0; i < classNames.size(); i++)
302 {
303 Array<CIMInstance> instances = enumerateInstancesForClass(nameSpace,
304 classNames[i], false, includeQualifiers, includeClassOrigin,
305 propertyList);
306
307 for (Uint32 i = 0 ; i < instances.size(); i++)
308 {
309 Filtering::filterInstance(
310 instances[i],
311 localOnly,
312 includeQualifiers,
313 includeClassOrigin,
314 propertyList);
315 }
316 mike 1.1.2.1
317 result.appendArray(instances);
318 }
319
320 return result;
321 }
322
323 Array<CIMInstance> MemoryResidentInstanceRepository::enumerateInstancesForClass(
324 const CIMNamespaceName& nameSpace,
325 const CIMName& className,
326 Boolean localOnly,
327 Boolean includeQualifiers,
328 Boolean includeClassOrigin,
329 const CIMPropertyList& propertyList)
330 {
331 TRACE;
332
333 Array<CIMInstance> result;
334
335 for (Uint32 i = 0; i < _rep.size(); i++)
336 {
337 mike 1.1.2.1 if (_rep[i].first != nameSpace)
338 continue;
339
340 CIMInstance& ci = _rep[i].second;
341
342 if (ci.getPath().getClassName() == className)
343 {
344 CIMInstance tmp = ci.clone();
345
346 Filtering::filterInstance(
347 tmp,
348 localOnly,
349 includeQualifiers,
350 includeClassOrigin,
351 propertyList);
352
353 result.append(tmp);
354 }
355 }
356
357 return result;
358 mike 1.1.2.1 }
359
360 Array<CIMObjectPath>
361 MemoryResidentInstanceRepository::enumerateInstanceNamesForSubtree(
362 const CIMNamespaceName& nameSpace,
363 const CIMName& className)
364 {
365 TRACE;
366
367 // Form array of classnames for this class and descendent classes:
368
369 Array<CIMName> classNames;
370 classNames.append(className);
371 MetaRepository::getSubClassNames(nameSpace, className, true, classNames);
372
373 // Get all instances for this class and all descendent classes
374
375 Array<CIMObjectPath> result;
376
377 for (Uint32 i = 0; i < classNames.size(); i++)
378 {
379 mike 1.1.2.1 Array<CIMObjectPath> paths =
380 enumerateInstanceNamesForClass(nameSpace, classNames[i]);
381
382 result.appendArray(paths);
383 }
384
385 return result;
386 }
387
388 Array<CIMObjectPath>
389 MemoryResidentInstanceRepository::enumerateInstanceNamesForClass(
390 const CIMNamespaceName& nameSpace,
391 const CIMName& className)
392 {
393 TRACE;
394
395 Array<CIMObjectPath> result;
396
397 for (Uint32 i = 0; i < _rep.size(); i++)
398 {
399 if (_rep[i].first != nameSpace)
400 mike 1.1.2.1 continue;
401
402 CIMInstance& ci = _rep[i].second;
403
404 if (ci.getPath().getClassName() == className)
405 result.append(ci.getPath());
406 }
407
408 return result;
409 }
410
411 Uint32 MemoryResidentInstanceRepository::_findInstance(
412 const CIMNamespaceName& nameSpace,
413 const CIMObjectPath& instanceName)
414 {
415 TRACE;
416
417 for (Uint32 i = 0; i < _rep.size(); i++)
418 {
419 if (_rep[i].first == nameSpace &&
420 _rep[i].second.getPath() == instanceName)
421 mike 1.1.2.1 {
422 return i;
423 }
424 }
425
426 return PEG_NOT_FOUND;
427 }
428
429 // ATTN-MEB: Implement associator operations!
430
431 PEGASUS_NAMESPACE_END
|