1 mike 1.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 // 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 "MRR.h"
35 #include <cstdarg>
36 #include <Pegasus/Common/Resolver.h>
37 #include <Pegasus/Common/Once.h>
38 #include <Pegasus/Common/System.h>
39 #include <Pegasus/Common/Tracer.h>
40 #include <Pegasus/Common/Pair.h>
41 #include "CIMRepository.h"
42 #include "RepositoryDeclContext.h"
43 mike 1.1 #include "MRRSerialization.h"
44 #include "MRRTypes.h"
45
46 PEGASUS_NAMESPACE_BEGIN
47
48 typedef Pair<CIMNamespaceName, CIMInstance> NamespaceInstancePair;
49
50 #define PEGASUS_ARRAY_T NamespaceInstancePair
51 # include <Pegasus/Common/ArrayInter.h>
52 #undef PEGASUS_ARRAY_T
53
54 class CIMRepositoryRep
55 {
56 public:
57
58 Uint32 _findInstance(
59 const CIMNamespaceName& nameSpace,
60 const CIMObjectPath& instanceName);
61
62 void _processSaveCallback();
63
64 mike 1.1 void _processLoadCallback();
65
66 Array<NamespaceInstancePair> _rep;
67 };
68
69 typedef const MRRClass* ConstMRRClassPtr;
70 #define PEGASUS_ARRAY_T ConstMRRClassPtr
71 # include <Pegasus/Common/ArrayInter.h>
72 # include <Pegasus/Common/ArrayImpl.h>
73 #undef PEGASUS_ARRAY_T
74
75 #define PEGASUS_ARRAY_T NamespaceInstancePair
76 # include <Pegasus/Common/ArrayImpl.h>
77 #undef PEGASUS_ARRAY_T
78
79 //==============================================================================
80 //
81 // Local definitions:
82 //
83 //==============================================================================
84
85 mike 1.1 static size_t const _MAX_NAMESPACE_TABLE_SIZE = 64;
86 static const MRRNameSpace* _nameSpaceTable[_MAX_NAMESPACE_TABLE_SIZE];
87 static size_t _nameSpaceTableSize = 0;
88
89 class ThrowContext
90 {
91 public:
92
93 PEGASUS_FORMAT(3, 4)
94 ThrowContext(CIMStatusCode code_, const char* format, ...) : code(code_)
95 {
96 char buffer[1024];
97 va_list ap;
98 va_start(ap, format);
99 vsprintf(buffer, format, ap);
100 va_end(ap);
101 msg = buffer;
102 }
103 CIMStatusCode code;
104 String msg;
105 };
106 mike 1.1
107 #define Throw(ARGS) \
108 do \
109 { \
110 ThrowContext c ARGS; \
111 throw CIMException(c.code, c.msg); \
112 } \
113 while (0)
114
115 class Str
116 {
117 public:
118 Str(const String& s) : _cstr(s.getCString()) { }
119 Str(const CIMName& n) : _cstr(n.getString().getCString()) { }
120 Str(const CIMNamespaceName& n) : _cstr(n.getString().getCString()) { }
121 Str(const Exception& e) : _cstr(e.getMessage().getCString()) { }
122 Str(const CIMDateTime& x) : _cstr(x.toString().getCString()) { }
123 Str(const CIMObjectPath& x) : _cstr(x.toString().getCString()) { }
124 const char* operator*() const { return (const char*)_cstr; }
125 operator const char*() const { return (const char*)_cstr; }
126 private:
127 mike 1.1 CString _cstr;
128 };
129
130 /** Check to see if the specified property is in the property list
131 @param property the specified property
132 @param propertyList the property list
133 @return true if the property is in the list otherwise false.
134 */
135 static Boolean _containsProperty(
136 CIMProperty& property,
137 const CIMPropertyList& propertyList)
138 {
139 // For each property in the propertly list
140 for (Uint32 p=0; p<propertyList.size(); p++)
141 {
142 if (propertyList[p].equal(property.getName()))
143 return true;
144 }
145 return false;
146 }
147
148 mike 1.1 /* removes all Qualifiers from a CIMClass. This function removes all
149 of the qualifiers from the class, from all of the properties,
150 from the methods, and from the parameters attached to the methods.
151 @param cimClass reference to the class from which qualifiers are to
152 be removed.
153 NOTE: This would be logical to be moved to CIMClass since it may be
154 more general than this usage.
155 */
156 static void _removeAllQualifiers(CIMClass& cimClass)
157 {
158 // remove qualifiers of the class
159 Uint32 count = 0;
160 while ((count = cimClass.getQualifierCount()) > 0)
161 cimClass.removeQualifier(count - 1);
162
163 // remove qualifiers from the properties
164 for (Uint32 i = 0; i < cimClass.getPropertyCount(); i++)
165 {
166 CIMProperty p = cimClass.getProperty(i);
167 count = 0;
168 while ((count = p.getQualifierCount()) > 0)
169 mike 1.1 p.removeQualifier(count - 1);
170 }
171
172 // remove qualifiers from the methods
173 for (Uint32 i = 0; i < cimClass.getMethodCount(); i++)
174 {
175 CIMMethod m = cimClass.getMethod(i);
176 for (Uint32 j = 0 ; j < m.getParameterCount(); j++)
177 {
178 CIMParameter p = m.getParameter(j);
179 count = 0;
180 while ((count = p.getQualifierCount()) > 0)
181 p.removeQualifier(count - 1);
182 }
183 count = 0;
184 while ((count = m.getQualifierCount()) > 0)
185 m.removeQualifier(count - 1);
186 }
187 }
188
189 /////////////////////////////////////////////////////////////////////////
190 mike 1.1 //
191 // _removePropagatedQualifiers - Removes all qualifiers from the class
192 // that are marked propagated
193 //
194 /////////////////////////////////////////////////////////////////////////
195
196 /* removes propagatedQualifiers from the defined CIMClass.
197 This function removes the qualifiers from the class,
198 from each of the properties, from the methods and
199 the parameters if the qualifiers are marked propagated.
200 NOTE: This could be logical to be moved to CIMClass since it may be
201 more general than the usage here.
202 */
203 static void _removePropagatedQualifiers(CIMClass& cimClass)
204 {
205 Uint32 count = cimClass.getQualifierCount();
206 // Remove nonlocal qualifiers from Class
207 for (Sint32 i = (count - 1); i >= 0; i--)
208 {
209 CIMQualifier q = cimClass.getQualifier(i);
210 if (q.getPropagated())
211 mike 1.1 {
212 cimClass.removeQualifier(i);
213 }
214 }
215
216 // remove non localOnly qualifiers from the properties
217 for (Uint32 i = 0; i < cimClass.getPropertyCount(); i++)
218 {
219 CIMProperty p = cimClass.getProperty(i);
220 // loop to search qualifiers for nonlocal parameters
221 count = p.getQualifierCount();
222 for (Sint32 j = (count - 1); j >= 0; j--)
223 {
224 CIMQualifier q = p.getQualifier(j);
225 if (q.getPropagated())
226 {
227 p.removeQualifier(j);
228 }
229 }
230 }
231
232 mike 1.1 // remove non LocalOnly qualifiers from the methods and parameters
233 for (Uint32 i = 0; i < cimClass.getMethodCount(); i++)
234 {
235 CIMMethod m = cimClass.getMethod(i);
236 // Remove nonlocal qualifiers from all parameters
237 for (Uint32 j = 0 ; j < m.getParameterCount(); j++)
238 {
239 CIMParameter p = m.getParameter(j);
240 count = p.getQualifierCount();
241 for (Sint32 k = (count - 1); k >= 0; k--)
242 {
243 CIMQualifier q = p.getQualifier(k);
244 if (q.getPropagated())
245 {
246 p.removeQualifier(k);
247 }
248 }
249 }
250
251 // remove nonlocal qualifiers from the method
252 count = m.getQualifierCount();
253 mike 1.1 for (Sint32 j = (count - 1); j >= 0; j--)
254 {
255 CIMQualifier q = m.getQualifier(j);
256 if (q.getPropagated())
257 {
258 m.removeQualifier(j);
259 }
260 }
261 }
262 }
263
264 /* remove the properties from an instance based on attributes.
265 @param Instance from which properties will be removed.
266 @param propertyList PropertyList is used in the removal algorithm
267 @param localOnly - Boolean used in the removal.
268 NOTE: This could be logical to move to CIMInstance since the
269 usage is more general than just in the repository
270 */
271 static void _removeProperties(
272 CIMInstance& cimInstance,
273 const CIMPropertyList& propertyList,
274 mike 1.1 Boolean localOnly)
275 {
276 Boolean propertyListNull = propertyList.isNull();
277 if ((!propertyListNull) || localOnly)
278 {
279 // Loop through properties to remove those that do not filter through
280 // local only attribute and are not in the property list.
281 Uint32 count = cimInstance.getPropertyCount();
282 // Work backwards because removal may be cheaper. Sint32 covers count=0
283 for (Sint32 i = (count - 1); i >= 0; i--)
284 {
285 CIMProperty p = cimInstance.getProperty(i);
286
287 // if localOnly == true, ignore properties defined in super class
288 if (localOnly && (p.getPropagated()))
289 {
290 cimInstance.removeProperty(i);
291 continue;
292 }
293
294 // propertyList NULL means deliver properties. PropertyList
295 mike 1.1 // empty, none.
296 // Test for removal if propertyList not NULL. The empty list option
297 // is covered by fact that property is not in the list.
298 if (!propertyListNull)
299 if (!_containsProperty(p, propertyList))
300 cimInstance.removeProperty(i);
301 }
302 }
303 }
304
305 /* remove all Qualifiers from a single CIMInstance. Removes
306 all of the qualifiers from the instance and from properties
307 within the instance.
308 @param instance from which parameters are removed.
309 NOTE: This could be logical to be moved to CIMInstance since
310 the usage may be more general than just in the repository.
311 */
312 static void _removeAllQualifiers(CIMInstance& cimInstance)
313 {
314 // remove qualifiers from the instance
315 Uint32 count = 0;
316 mike 1.1 while ((count = cimInstance.getQualifierCount()) > 0)
317 cimInstance.removeQualifier(count - 1);
318
319 // remove qualifiers from the properties
320 for (Uint32 i = 0; i < cimInstance.getPropertyCount(); i++)
321 {
322 CIMProperty p = cimInstance.getProperty(i);
323 count = 0;
324 while ((count = p.getQualifierCount()) > 0)
325 p.removeQualifier(count - 1);
326 }
327 }
328
329 /* removes all ClassOrigin attributes from a single CIMInstance. Removes
330 the classOrigin attribute from each property in the Instance.
331 @param Instance from which the ClassOrigin Properties will be removed.
332 NOTE: Logical to be moved to CIMInstance since it may be more general
333 than just the repositoryl
334 */
335 void _removeClassOrigins(CIMInstance& cimInstance)
336 {
337 mike 1.1 PEG_TRACE_CSTRING(TRC_REPOSITORY, Tracer::LEVEL4, "Remove Class Origins");
338
339 Uint32 propertyCount = cimInstance.getPropertyCount();
340 for (Uint32 i = 0; i < propertyCount ; i++)
341 cimInstance.getProperty(i).setClassOrigin(CIMName());
342 }
343
344 /* Filters the properties, qualifiers, and classorigin out of a single instance.
345 Based on the parameters provided for localOnly, includeQualifiers,
346 and includeClassOrigin, this function simply filters the properties
347 qualifiers, and classOrigins out of a single instance. This function
348 was created to have a single piece of code that processes getinstance
349 and enumerateInstances returns.
350 @param cimInstance reference to instance to be processed.
351 @param localOnly defines if request is for localOnly parameters.
352 @param includeQualifiers Boolean defining if qualifiers to be returned.
353 @param includeClassOrigin Boolean defining if ClassOrigin attribute to
354 be removed from properties.
355 */
356 static void _filterInstance(
357 CIMInstance& cimInstance,
358 mike 1.1 Boolean localOnly,
359 Boolean includeQualifiers,
360 Boolean includeClassOrigin,
361 const CIMPropertyList& propertyList)
362 {
363 // Remove properties based on propertyList and localOnly flag
364 _removeProperties(cimInstance, propertyList, localOnly);
365
366 // If includequalifiers false, remove all qualifiers from
367 // properties.
368
369 if (!includeQualifiers)
370 {
371 _removeAllQualifiers(cimInstance);
372 }
373
374 // if ClassOrigin Flag false, remove classOrigin info from Instance object
375 // by setting the classOrigin to Null.
376
377 if (!includeClassOrigin)
378 {
379 mike 1.1 _removeClassOrigins(cimInstance);
380 }
381 }
382
383 static void _filterClass(
384 CIMClass& cimClass,
385 Boolean localOnly,
386 Boolean includeQualifiers,
387 Boolean includeClassOrigin,
388 const CIMPropertyList& propertyList)
389 {
390 // Remove properties based on propertylist and localOnly flag (Bug 565)
391 Boolean propertyListNull = propertyList.isNull();
392
393 // if localOnly OR there is a property list, process properties
394 if ((!propertyListNull) || localOnly)
395 {
396 // Loop through properties to remove those that do not filter through
397 // local only attribute and are not in the property list.
398 Uint32 count = cimClass.getPropertyCount();
399 // Work backwards because removal may be cheaper. Sint32 covers count=0
400 mike 1.1 for (Sint32 i = (count - 1); i >= 0; i--)
401 {
402 CIMProperty p = cimClass.getProperty(i);
403 // if localOnly==true, ignore properties defined in super class
404 if (localOnly && (p.getPropagated()))
405 {
406 cimClass.removeProperty(i);
407 continue;
408 }
409
410 // propertyList NULL means all properties. PropertyList
411 // empty, none.
412 // Test for removal if propertyList not NULL. The empty list option
413 // is covered by fact that property is not in the list.
414 if (!propertyListNull)
415 if (!_containsProperty(p, propertyList))
416 cimClass.removeProperty(i);
417 }
418 }
419
420 // remove methods based on localOnly flag
421 mike 1.1 if (localOnly)
422 {
423 Uint32 count = cimClass.getMethodCount();
424 // Work backwards because removal may be cheaper.
425 for (Sint32 i = (count - 1); i >= 0; i--)
426 {
427 CIMMethod m = cimClass.getMethod(i);
428
429 // if localOnly==true, ignore properties defined in super class
430 if (localOnly && (m.getPropagated()))
431 cimClass.removeMethod(i);
432 }
433
434 }
435 // If includequalifiers false, remove all qualifiers from
436 // properties, methods and parameters.
437 if (!includeQualifiers)
438 {
439 _removeAllQualifiers(cimClass);
440 }
441 else
442 mike 1.1 {
443 // if includequalifiers and localOnly, remove nonLocal qualifiers
444 if (localOnly)
445 {
446 _removePropagatedQualifiers(cimClass);
447 }
448
449 }
450
451
452 // if ClassOrigin Flag false, remove classOrigin info from class object
453 // by setting the property to Null.
454 if (!includeClassOrigin)
455 {
456 PEG_TRACE_CSTRING(TRC_REPOSITORY, Tracer::LEVEL4,
457 "Remove Class Origins");
458
459 Uint32 propertyCount = cimClass.getPropertyCount();
460 for (Uint32 i = 0; i < propertyCount ; i++)
461 cimClass.getProperty(i).setClassOrigin(CIMName());
462
463 mike 1.1 Uint32 methodCount = cimClass.getMethodCount();
464 for (Uint32 i=0; i < methodCount ; i++)
465 cimClass.getMethod(i).setClassOrigin(CIMName());
466 }
467 }
468
469
470 static bool _contains(const CIMPropertyList& propertyList, const CIMName& name)
471 {
472 for (Uint32 i = 0; i < propertyList.size(); i++)
473 {
474 if (propertyList[i] == name)
475 return true;
476 }
477
478 return false;
479 }
480
481 static void _applyModifiedInstance(
482 const MRRClass* sc,
483 const CIMInstance& modifiedInstance_,
484 mike 1.1 const CIMPropertyList& propertyList,
485 CIMInstance& resultInstance)
486 {
487 CIMInstance& modifiedInstance = *((CIMInstance*)&modifiedInstance_);
488
489 for (Uint32 i = 0; i < modifiedInstance.getPropertyCount(); i++)
490 {
491 CIMProperty cp = modifiedInstance.getProperty(i);
492 Uint32 pos = resultInstance.findProperty(cp.getName());
493
494 if (propertyList.isNull() || _contains(propertyList, cp.getName()))
495 {
496 // Reject attempts to add properties not in class:
497
498 const MRRFeature* sf = FindFeature(sc,
499 *Str(cp.getName()), MRR_FLAG_PROPERTY|MRR_FLAG_REFERENCE);
500
501 if (!sf)
502 {
503 Throw((CIM_ERR_NOT_FOUND,
504 "modifyInstance() failed: unknown property: %s",
505 mike 1.1 *Str(cp.getName())));
506 }
507
508 // Reject attempts to modify key properties:
509
510 if (sf->flags & MRR_FLAG_KEY)
511 {
512 Throw((CIM_ERR_FAILED,
513 "modifyInstance() failed to modify key property: %s",
514 *Str(cp.getName())));
515 }
516
517 // Add or replace property in result instance:
518
519 if (pos != PEG_NOT_FOUND)
520 resultInstance.removeProperty(pos);
521
522 resultInstance.addProperty(cp);
523 }
524 }
525 }
526 mike 1.1
527 static void _print(const CIMInstance& ci)
528 {
529 CIMObject co(ci);
530
531 std::cout << co.toString() << std::endl;
532 }
533
534 static Once _once = PEGASUS_ONCE_INITIALIZER;
535 static const char* _hostName = 0;
536
537 static void _initHostName()
538 {
539 String hn = System::getHostName();
540 _hostName = strdup(*Str(hn));
541 }
542
543 static inline const char* _getHostName()
544 {
545 once(&_once, _initHostName);
546 return _hostName;
547 mike 1.1 }
548
549 static bool _eqi(const char* s1, const char* s2)
550 {
551 return System::strcasecmp(s1, s2) == 0;
552 }
553
554 static const MRRNameSpace* _findNameSpace(const char* name)
555 {
556 for (size_t i = 0; i < _nameSpaceTableSize; i++)
557 {
558 const MRRNameSpace* ns = _nameSpaceTable[i];
559
560 if (_eqi(ns->name, name))
561 return ns;
562 }
563
564 // Not found!
565 return 0;
566 }
567
568 mike 1.1 static bool _isSubClass(const MRRClass* super, const MRRClass* sub)
569 {
570 if (!super)
571 return true;
572
573 for (MRRClass* p = sub->super; p; p = p->super)
574 {
575 if (p == super)
576 return true;
577 }
578
579 return false;
580 }
581
582 static inline bool _isDirectSubClass(
583 const MRRClass* super,
584 const MRRClass* sub)
585 {
586 return sub->super == super;
587 }
588
589 mike 1.1 static char** _makePropertyList(const CIMPropertyList& propertyList)
590 {
591 if (propertyList.isNull())
592 return 0;
593
594 size_t size = propertyList.size();
595 char** pl = (char**)malloc(sizeof(char*) * (size + 1));
596
597 for (size_t i = 0; i < size; i++)
598 pl[i] = strdup(*Str(propertyList[i]));
599
600 pl[size] = 0;
601
602 return pl;
603 }
604
605 static void _freePropertyList(char** pl)
606 {
607 if (!pl)
608 return;
609
610 mike 1.1 for (size_t i = 0; pl[i]; i++)
611 {
612 free(pl[i]);
613 }
614
615 free(pl);
616 }
617
618 static void _printPropertyList(const char* const* pl)
619 {
620 if (!pl)
621 return;
622
623 for (size_t i = 0; pl[i]; i++)
624 printf("pl[%s]\n", pl[i]);
625 }
626
627 static bool _contains(const Array<const MRRClass*>& x, const MRRClass* sc)
628 {
629 Uint32 n = x.size();
630 const MRRClass* const* p = x.getData();
631 mike 1.1
632 while (n--)
633 {
634 if (*p++ == sc)
635 return true;
636 }
637
638 return false;
639 }
640
641 static void _associators(
642 const MRRNameSpace* ns,
643 const CIMName& className,
644 const CIMName& assocClass,
645 const CIMName& resultClass,
646 const String& role,
647 const String& resultRole,
648 Array<const MRRClass*>& result)
649 {
650 // Lookup source class:
651
652 mike 1.1 const MRRClass* sc = FindClass(ns, *Str(className));
653
654 if (!sc)
655 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
656
657
658 // Lookup result class (if any).
659
660 const MRRClass* rmc = 0;
661
662 if (!resultClass.isNull())
663 {
664 rmc = FindClass(ns, *Str(resultClass));
665
666 if (!rmc)
667 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(resultClass)));
668 }
669
670 // Convert these to UTF8 now to avoid doing so in loop below.
671
672 Str ac(assocClass);
673 mike 1.1 Str r(role);
674 Str rr(resultRole);
675
676 // Process association classes:
677
678 for (size_t i = 0; ns->classes[i]; i++)
679 {
680 MRRClass* amc = ns->classes[i];
681
682 // Skip non-association classes:
683
684 if (!(amc->flags & MRR_FLAG_ASSOCIATION))
685 continue;
686
687 // Filter by assocClass parameter:
688
689 if (!assocClass.isNull() && !_eqi(ac, amc->name))
690 continue;
691
692 // Process reference properties:
693
694 mike 1.1 MRRFeatureInfo features[MRR_MAX_FEATURES];
695 size_t size = 0;
696 MergeFeatures(amc, false, MRR_FLAG_REFERENCE, features, size);
697
698 for (size_t j = 0; j < size; j++)
699 {
700 const MRRFeature* sf = features[j].sf;
701
702 // Skip non references:
703
704 if (!(sf->flags & MRR_FLAG_REFERENCE))
705 continue;
706
707 const MRRReference* sr = (const MRRReference*)sf;
708
709 // Filter by role parameter.
710
711 if (role.size() && !_eqi(r, sf->name))
712 continue;
713
714 // Filter by source class:
715 mike 1.1
716 if (!IsA(sr->ref, sc))
717 continue;
718
719 // Process result reference:
720
721 for (size_t k = 0; k < size; k++)
722 {
723 const MRRFeature* rmf = features[k].sf;
724
725 // Skip the feature under consideration:
726
727 if (rmf == sf)
728 continue;
729
730 // Skip non references:
731
732 if (!(rmf->flags & MRR_FLAG_REFERENCE))
733 continue;
734
735 const MRRReference* rmr = (const MRRReference*)rmf;
736 mike 1.1
737 // Filter by resultRole parameter.
738
739 if (resultRole.size() && !_eqi(rr, rmf->name))
740 continue;
741
742 // Skip references not of the result class kind:
743
744 if (rmc && !IsA(rmr->ref, rmc))
745 continue;
746
747 // ATTN: should we include entire class hierarchy under
748 // result class?
749
750 // If reached, then save this one.
751
752 if (!_contains(result, rmr->ref))
753 result.append(rmr->ref);
754 }
755 }
756 }
757 mike 1.1 }
758
759 static void _references(
760 const MRRNameSpace* ns,
761 const CIMName& className,
762 const CIMName& resultClass,
763 const String& role,
764 Array<const MRRClass*>& result)
765 {
766 // Lookup source class:
767
768 const MRRClass* sc = FindClass(ns, *Str(className));
769
770 if (!sc)
771 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
772
773 // Lookup result class (if any).
774
775 const MRRClass* rmc = 0;
776
777 if (!resultClass.isNull())
778 mike 1.1 {
779 rmc = FindClass(ns, *Str(resultClass));
780
781 if (!rmc)
782 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(resultClass)));
783 }
784
785 // Convert these to UTF8 now to avoid doing so in loop below.
786
787 Str r(role);
788
789 // Process association classes:
790
791 for (size_t i = 0; ns->classes[i]; i++)
792 {
793 MRRClass* amc = ns->classes[i];
794
795 // Skip non-association classes:
796
797 if (!(amc->flags & MRR_FLAG_ASSOCIATION))
798 continue;
799 mike 1.1
800 // Filter by result class:
801
802 if (rmc && !IsA(rmc, amc))
803 continue;
804
805 // Process reference properties:
806
807 MRRFeatureInfo features[MRR_MAX_FEATURES];
808 size_t size = 0;
809 MergeFeatures(amc, false, MRR_FLAG_REFERENCE, features, size);
810
811 for (size_t j = 0; j < size; j++)
812 {
813 const MRRFeature* sf = features[j].sf;
814
815 // Skip non references:
816
817 if (!(sf->flags & MRR_FLAG_REFERENCE))
818 continue;
819
820 mike 1.1 const MRRReference* sr = (const MRRReference*)sf;
821
822 // Filter by role parameter.
823
824 if (role.size() && !_eqi(r, sf->name))
825 continue;
826
827 // Filter by source class:
828
829 if (!IsA(sr->ref, sc))
830 continue;
831
832 // Add this one to the output:
833
834 if (!_contains(result, amc))
835 result.append((MRRClass*)amc);
836 }
837 }
838 }
839
840 static const MRRClass* _findMRRClass(
841 mike 1.1 const char* nameSpace,
842 const char* className)
843 {
844 // Lookup namespace:
845
846 const MRRNameSpace* ns = _findNameSpace(nameSpace);
847
848 if (!ns)
849 return 0;
850
851 return FindClass(ns, className);
852 }
853
854 static Array<CIMName> _enumerateClassNames(
855 const CIMNamespaceName& nameSpace,
856 const CIMName& className,
857 Boolean deepInheritance)
858 {
859 // Lookup namespace:
860
861 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
862 mike 1.1
863 if (!ns)
864 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
865
866 // Lookup class:
867
868 const MRRClass* super = 0;
869
870 if (!className.isNull())
871 {
872 super = FindClass(ns, *Str(className));
873
874 if (!super)
875 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
876 }
877
878 // Iterate all classes looking for matches:
879
880 Array<CIMName> result;
881
882 for (size_t i = 0; ns->classes[i]; i++)
883 mike 1.1 {
884 MRRClass* sc = ns->classes[i];
885
886 if (deepInheritance)
887 {
888 if (_isSubClass(super, sc))
889 result.append(sc->name);
890 }
891 else
892 {
893 if (_isDirectSubClass(super, sc))
894 result.append(sc->name);
895 }
896 }
897
898 return result;
899 }
900
901 static void _getSubClassNames(
902 const CIMNamespaceName& nameSpace,
903 const CIMName& className,
904 mike 1.1 Boolean deepInheritance,
905 Array<CIMName>& subClassNames)
906 {
907 subClassNames = _enumerateClassNames(
908 nameSpace, className, deepInheritance);
909 }
910
911 static Array<CIMObject> _associatorClasses(
912 const CIMNamespaceName& nameSpace,
913 const CIMName& className,
914 const CIMName& assocClass,
915 const CIMName& resultClass,
916 const String& role,
917 const String& resultRole,
918 Boolean includeQualifiers,
919 Boolean includeClassOrigin,
920 const CIMPropertyList& propertyList)
921 {
922 // Lookup namespace:
923
924 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
925 mike 1.1
926 if (!ns)
927 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
928
929 // Get associator schema-classes:
930
931 Array<const MRRClass*> mcs;
932 _associators(ns, className, assocClass, resultClass, role, resultRole, mcs);
933
934 // Convert schema-classes to classes.
935
936 Array<CIMObject> result;
937
938 char** pl = _makePropertyList(propertyList);
939
940 for (Uint32 i = 0; i < mcs.size(); i++)
941 {
942 const MRRClass* sc = mcs[i];
943 CIMClass cc;
944
945 if (MakeClass(_getHostName(), ns, sc, false, includeQualifiers,
946 mike 1.1 includeClassOrigin, pl, cc) != 0)
947 {
948 _freePropertyList(pl);
949 Throw((CIM_ERR_FAILED, "conversion failed: %s", sc->name));
950 }
951
952 result.append(cc);
953 }
954
955 _freePropertyList(pl);
956 return result;
957 }
958
959 static Array<CIMObjectPath> _associatorClassPaths(
960 const CIMNamespaceName& nameSpace,
961 const CIMName& className,
962 const CIMName& assocClass,
963 const CIMName& resultClass,
964 const String& role,
965 const String& resultRole)
966 {
967 mike 1.1 // Lookup namespace:
968
969 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
970
971 if (!ns)
972 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
973
974 // Get associator schema-classes:
975
976 Array<const MRRClass*> mcs;
977 _associators(ns, className, assocClass, resultClass, role, resultRole, mcs);
978
979 // Convert schema-classes to object names:
980
981 Array<CIMObjectPath> result;
982
983 for (Uint32 i = 0; i < mcs.size(); i++)
984 result.append(CIMObjectPath(_getHostName(), nameSpace, mcs[i]->name));
985
986 return result;
987 }
988 mike 1.1
989 static Array<CIMObject> _referenceClasses(
990 const CIMNamespaceName& nameSpace,
991 const CIMName& className,
992 const CIMName& resultClass,
993 const String& role,
994 Boolean includeQualifiers,
995 Boolean includeClassOrigin,
996 const CIMPropertyList& propertyList)
997 {
998 // Lookup namespace:
999
1000 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1001
1002 if (!ns)
1003 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1004
1005 // Get reference schema-classes:
1006
1007 Array<const MRRClass*> mcs;
1008 _references(ns, className, resultClass, role, mcs);
1009 mike 1.1
1010 // Convert schema-classes to classes.
1011
1012 Array<CIMObject> result;
1013
1014 char** pl = _makePropertyList(propertyList);
1015
1016 for (Uint32 i = 0; i < mcs.size(); i++)
1017 {
1018 const MRRClass* sc = mcs[i];
1019 CIMClass cc;
1020
1021 if (MakeClass(_getHostName(), ns, sc, false, includeQualifiers,
1022 includeClassOrigin, pl, cc) != 0)
1023 {
1024 _freePropertyList(pl);
1025 Throw((CIM_ERR_FAILED, "conversion failed: %s", sc->name));
1026 }
1027
1028 result.append(cc);
1029 }
1030 mike 1.1
1031 _freePropertyList(pl);
1032 return result;
1033 }
1034
1035 static Array<CIMObjectPath> _referenceClassPaths(
1036 const CIMNamespaceName& nameSpace,
1037 const CIMName& className,
1038 const CIMName& resultClass,
1039 const String& role)
1040 {
1041 // Lookup namespace:
1042
1043 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1044
1045 if (!ns)
1046 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1047
1048 // Get reference schema-classes:
1049
1050 Array<const MRRClass*> mcs;
1051 mike 1.1 _references(ns, className, resultClass, role, mcs);
1052
1053 // Convert schema-classes to object paths.
1054
1055 Array<CIMObjectPath> result;
1056
1057 for (Uint32 i = 0; i < mcs.size(); i++)
1058 result.append(CIMObjectPath(_getHostName(), nameSpace, mcs[i]->name));
1059
1060 return result;
1061 }
1062
1063 static CIMQualifierDecl _getQualifier(
1064 const CIMNamespaceName& nameSpace,
1065 const CIMName& qualifierName)
1066 {
1067 // Lookup namespace:
1068
1069 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1070
1071 if (!ns)
1072 mike 1.1 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1073
1074 // Lookup qualifier:
1075
1076 const MRRQualifierDecl* mqd = FindQualifierDecl(ns, *Str(qualifierName));
1077
1078 if (!mqd)
1079 Throw((CIM_ERR_NOT_FOUND,
1080 "unknown qualifier: %s", *Str(qualifierName)));
1081
1082 // Make the qualifier declaration:
1083
1084 CIMQualifierDecl cqd;
1085
1086 if (MakeQualifierDecl(ns, mqd, cqd) != 0)
1087 {
1088 Throw((CIM_ERR_FAILED, "conversion failed: %s", mqd->name));
1089 }
1090
1091 return cqd;
1092 }
1093 mike 1.1
1094 static Array<CIMQualifierDecl> _enumerateQualifiers(
1095 const CIMNamespaceName& nameSpace)
1096 {
1097 // Lookup namespace:
1098
1099 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1100
1101 if (!ns)
1102 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1103
1104 // Build the array of qualifier declarations:
1105
1106 Array<CIMQualifierDecl> result;
1107
1108 for (size_t i = 0; ns->qualifiers[i]; i++)
1109 {
1110 const MRRQualifierDecl* mqd = ns->qualifiers[i];
1111 CIMQualifierDecl cqd;
1112
1113 if (MakeQualifierDecl(ns, mqd, cqd) != 0)
1114 mike 1.1 {
1115 Throw((CIM_ERR_FAILED, "conversion failed: %s", mqd->name));
1116 }
1117
1118 result.append(cqd);
1119 }
1120
1121 return result;
1122
1123 }
1124
1125 static Array<CIMNamespaceName> _enumerateNameSpaces()
1126 {
1127 Array<CIMNamespaceName> result;
1128
1129 for (size_t i = 0; i < _nameSpaceTableSize; i++)
1130 {
1131 const MRRNameSpace* ns = _nameSpaceTable[i];
1132 result.append(ns->name);
1133 }
1134
1135 mike 1.1 return result;
1136 }
1137
1138 static void _getSuperClassNames(
1139 const CIMNamespaceName& nameSpace,
1140 const CIMName& className,
1141 Array<CIMName>& superClassNames)
1142 {
1143 superClassNames.clear();
1144
1145 // Lookup namespace:
1146
1147 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1148
1149 if (!ns)
1150 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1151
1152 // Lookup class:
1153
1154 const MRRClass* sc = FindClass(ns, *Str(className));
1155
1156 mike 1.1 if (!sc)
1157 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
1158
1159 // Append superclass names:
1160
1161 for (const MRRClass* p = sc->super; p; p = p->super)
1162 superClassNames.append(p->name);
1163 }
1164
1165 //==============================================================================
1166 //
1167 // class CIMRepository:
1168 //
1169 //==============================================================================
1170
1171 static void (*_saveCallback)(const Buffer& buffer, void* data);
1172 static void* _saveData;
1173
1174 static void (*_loadCallback)(Buffer& buffer, void* data);
1175 static void* _loadData;
1176
1177 mike 1.1 static void (*_initializeCallback)(CIMRepository* rep, void* data);
1178 static void* _initializeData;
1179
1180 CIMRepository::CIMRepository(
1181 const String& repositoryRoot,
1182 Uint32 mode,
1183 RepositoryDeclContext* declContext)
1184 {
1185 /* ATTN: declContext is not used here! */
1186
1187 _rep = new CIMRepositoryRep;
1188
1189 // Load users data if any:
1190 _rep->_processLoadCallback();
1191
1192 // Call initialize callback if any.
1193
1194 if (_initializeCallback)
1195 (*_initializeCallback)(this, _initializeData);
1196 }
1197
1198 mike 1.1 CIMRepository::~CIMRepository()
1199 {
1200 delete _rep;
1201 }
1202
1203 CIMClass CIMRepository::getClass(
1204 const CIMNamespaceName& nameSpace,
1205 const CIMName& className,
1206 Boolean localOnly,
1207 Boolean includeQualifiers,
1208 Boolean includeClassOrigin,
1209 const CIMPropertyList& propertyList)
1210 {
1211 // Lookup namespace:
1212
1213 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1214
1215 if (!ns)
1216 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1217
1218 // Lookup class:
1219 mike 1.1
1220 const MRRClass* sc = FindClass(ns, *Str(className));
1221
1222 if (!sc)
1223 {
1224 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
1225 }
1226
1227 // Build property list:
1228
1229 char** pl = _makePropertyList(propertyList);
1230
1231 // Make class:
1232
1233 CIMClass cc;
1234
1235 if (MakeClass(_getHostName(), ns, sc, localOnly, includeQualifiers,
1236 includeClassOrigin, pl, cc) != 0)
1237 {
1238 _freePropertyList(pl);
1239 Throw((CIM_ERR_FAILED, "conversion failed: %s", sc->name));
1240 mike 1.1 }
1241
1242 _freePropertyList(pl);
1243 return cc;
1244 }
1245
1246 CIMInstance CIMRepository::getInstance(
1247 const CIMNamespaceName& nameSpace,
1248 const CIMObjectPath& instanceName,
1249 Boolean localOnly,
1250 Boolean includeQualifiers,
1251 Boolean includeClassOrigin,
1252 const CIMPropertyList& propertyList)
1253 {
1254 Uint32 pos = _rep->_findInstance(nameSpace, instanceName);
1255
1256 if (pos == PEG_NOT_FOUND)
1257 Throw((CIM_ERR_NOT_FOUND, "%s", *Str(instanceName)));
1258
1259 CIMInstance cimInstance = _rep->_rep[pos].second.clone();
1260
1261 mike 1.1 _filterInstance(
1262 cimInstance,
1263 localOnly,
1264 includeQualifiers,
1265 includeClassOrigin,
1266 propertyList);
1267
1268 return cimInstance;
1269 }
1270
1271 void CIMRepository::deleteClass(
1272 const CIMNamespaceName& nameSpace,
1273 const CIMName& className)
1274 {
1275 Throw((CIM_ERR_NOT_SUPPORTED, "deleteClass()"));
1276 }
1277
1278 void CIMRepository::deleteInstance(
1279 const CIMNamespaceName& nameSpace,
1280 const CIMObjectPath& instanceName)
1281 {
1282 mike 1.1 Uint32 pos = _rep->_findInstance(nameSpace, instanceName);
1283
1284 if (pos == PEG_NOT_FOUND)
1285 Throw((CIM_ERR_NOT_FOUND, "%s", *Str(instanceName)));
1286
1287 _rep->_rep.remove(pos);
1288 _rep->_processSaveCallback();
1289 }
1290
1291 void CIMRepository::createClass(
1292 const CIMNamespaceName& nameSpace,
1293 const CIMClass& newClass,
1294 const ContentLanguageList& contentLangs)
1295 {
1296 Throw((CIM_ERR_NOT_SUPPORTED, "createClass()"));
1297 }
1298
1299 CIMObjectPath CIMRepository::createInstance(
1300 const CIMNamespaceName& nameSpace,
1301 const CIMInstance& newInstance,
1302 const ContentLanguageList& contentLangs)
1303 mike 1.1 {
1304 // Resolve the instance first:
1305
1306 CIMInstance ci(newInstance.clone());
1307 CIMConstClass cc;
1308 RepositoryDeclContext context;
1309 context.setRepository(this);
1310 Resolver::resolveInstance(ci, &context, nameSpace, cc, false);
1311 CIMObjectPath cop = ci.buildPath(cc);
1312
1313 ci.setPath(cop);
1314
1315 // Reject if an instance with this name already exists:
1316
1317 if (_rep->_findInstance(nameSpace, cop) != PEG_NOT_FOUND)
1318 Throw((CIM_ERR_ALREADY_EXISTS, "%s", *Str(cop)));
1319
1320 // Add instance to array:
1321
1322 _rep->_rep.append(NamespaceInstancePair(nameSpace, ci));
1323 _rep->_processSaveCallback();
1324 mike 1.1
1325 return cop;
1326 }
1327
1328 void CIMRepository::modifyClass(
1329 const CIMNamespaceName& nameSpace,
1330 const CIMClass& modifiedClass,
1331 const ContentLanguageList& contentLangs)
1332 {
1333 Throw((CIM_ERR_NOT_SUPPORTED, "modifyClass()"));
1334 }
1335
1336 void CIMRepository::modifyInstance(
1337 const CIMNamespaceName& nameSpace,
1338 const CIMInstance& modifiedInstance,
1339 Boolean includeQualifiers,
1340 const CIMPropertyList& propertyList,
1341 const ContentLanguageList& contentLangs)
1342 {
1343 const CIMObjectPath& cop = modifiedInstance.getPath();
1344 CIMName className = cop.getClassName();
1345 mike 1.1
1346 // Get the schema-class for this instance.
1347
1348 const MRRClass* sc = _findMRRClass(*Str(nameSpace), *Str(className));
1349
1350 if (!sc)
1351 {
1352 Throw((CIM_ERR_FAILED,
1353 "modifyInstance() failed: unknown class: %s:%s",
1354 *Str(nameSpace), *Str(className)));
1355 }
1356
1357 // Get original instance to be modified:
1358
1359 Uint32 pos = _rep->_findInstance(nameSpace, cop);
1360
1361 if (pos == PEG_NOT_FOUND)
1362 {
1363 Throw((CIM_ERR_NOT_FOUND,
1364 "modifyInstance() failed: unknown instance: %s",
1365 *Str(cop.toString())));
1366 mike 1.1 }
1367
1368 CIMInstance resultInstance = _rep->_rep[pos].second.clone();
1369
1370 // Apply features of modifiedInstance to result instance.
1371
1372 _applyModifiedInstance(sc, modifiedInstance, propertyList, resultInstance);
1373
1374 // Resolve the instance.
1375
1376 CIMConstClass cc;
1377 RepositoryDeclContext context;
1378 context.setRepository(this);
1379 Resolver::resolveInstance(resultInstance, &context, nameSpace, cc, false);
1380
1381 // Replace original instance.
1382
1383 _rep->_rep[pos].second = resultInstance;
1384 _rep->_processSaveCallback();
1385 }
1386
1387 mike 1.1 Array<CIMClass> CIMRepository::enumerateClasses(
1388 const CIMNamespaceName& nameSpace,
1389 const CIMName& className,
1390 Boolean deepInheritance,
1391 Boolean localOnly,
1392 Boolean includeQualifiers,
1393 Boolean includeClassOrigin)
1394 {
1395 // Lookup namespace:
1396
1397 const MRRNameSpace* ns = _findNameSpace(*Str(nameSpace));
1398
1399 if (!ns)
1400 Throw((CIM_ERR_INVALID_NAMESPACE, "%s", *Str(nameSpace)));
1401
1402 // Lookup class:
1403
1404 const MRRClass* super = 0;
1405
1406 if (!className.isNull())
1407 {
1408 mike 1.1 super = FindClass(ns, *Str(className));
1409
1410 if (!super)
1411 Throw((CIM_ERR_NOT_FOUND, "unknown class: %s", *Str(className)));
1412 }
1413
1414 // Iterate all classes looking for matches:
1415
1416 Array<CIMClass> result;
1417
1418 for (size_t i = 0; ns->classes[i]; i++)
1419 {
1420 MRRClass* sc = ns->classes[i];
1421
1422 bool flag = false;
1423
1424 if (deepInheritance)
1425 {
1426 if (_isSubClass(super, sc))
1427 flag = true;
1428 }
1429 mike 1.1 else
1430 {
1431 if (_isDirectSubClass(super, sc))
1432 flag = true;
1433 }
1434
1435 if (flag)
1436 {
1437 CIMClass cc;
1438
1439 if (MakeClass(_getHostName(), ns, sc, localOnly, includeQualifiers,
1440 includeClassOrigin, 0, cc) != 0)
1441 {
1442 Throw((CIM_ERR_FAILED, "conversion failed: %s", sc->name));
1443 }
1444
1445 result.append(cc);
1446 }
1447 }
1448
1449 return result;
1450 mike 1.1 }
1451
1452 Array<CIMName> CIMRepository::enumerateClassNames(
1453 const CIMNamespaceName& nameSpace,
1454 const CIMName& className,
1455 Boolean deepInheritance)
1456 {
1457 return _enumerateClassNames(nameSpace, className, deepInheritance);
1458 }
1459
1460 Array<CIMInstance> CIMRepository::enumerateInstancesForSubtree(
1461 const CIMNamespaceName& nameSpace,
1462 const CIMName& className,
1463 Boolean deepInheritance,
1464 Boolean localOnly,
1465 Boolean includeQualifiers,
1466 Boolean includeClassOrigin,
1467 const CIMPropertyList& propertyList)
1468 {
1469 // Form array of classnames for this class and descendent classes:
1470
1471 mike 1.1 Array<CIMName> classNames;
1472 classNames.append(className);
1473 _getSubClassNames(nameSpace, className, true, classNames);
1474
1475 // Get all instances for this class and all descendent classes
1476
1477 Array<CIMInstance> result;
1478
1479 for (Uint32 i = 0; i < classNames.size(); i++)
1480 {
1481 Array<CIMInstance> instances = enumerateInstancesForClass(
1482 nameSpace, classNames[i], false, includeQualifiers,
1483 includeClassOrigin, propertyList);
1484
1485 for (Uint32 i = 0 ; i < instances.size(); i++)
1486 {
1487 _filterInstance(
1488 instances[i],
1489 localOnly,
1490 includeQualifiers,
1491 includeClassOrigin,
1492 mike 1.1 propertyList);
1493 }
1494
1495 result.appendArray(instances);
1496 }
1497
1498 return result;
1499 }
1500
1501 Array<CIMInstance> CIMRepository::enumerateInstancesForClass(
1502 const CIMNamespaceName& nameSpace,
1503 const CIMName& className,
1504 Boolean localOnly,
1505 Boolean includeQualifiers,
1506 Boolean includeClassOrigin,
1507 const CIMPropertyList& propertyList)
1508 {
1509 Array<CIMInstance> result;
1510
1511 for (Uint32 i = 0; i < _rep->_rep.size(); i++)
1512 {
1513 mike 1.1 if (_rep->_rep[i].first != nameSpace)
1514 continue;
1515
1516 CIMInstance& ci = _rep->_rep[i].second;
1517
1518 if (ci.getPath().getClassName() == className)
1519 {
1520 CIMInstance tmp = ci.clone();
1521
1522 _filterInstance(
1523 tmp,
1524 localOnly,
1525 includeQualifiers,
1526 includeClassOrigin,
1527 propertyList);
1528
1529 result.append(tmp);
1530 }
1531 }
1532
1533 return result;
1534 mike 1.1 }
1535
1536 Array<CIMObjectPath> CIMRepository::enumerateInstanceNamesForSubtree(
1537 const CIMNamespaceName& nameSpace,
1538 const CIMName& className)
1539 {
1540 // Form array of classnames for this class and descendent classes:
1541
1542 Array<CIMName> classNames;
1543 classNames.append(className);
1544 _getSubClassNames(nameSpace, className, true, classNames);
1545
1546 // Get all instances for this class and all descendent classes
1547
1548 Array<CIMObjectPath> result;
1549
1550 for (Uint32 i = 0; i < classNames.size(); i++)
1551 {
1552 Array<CIMObjectPath> paths = enumerateInstanceNamesForClass(
1553 nameSpace, classNames[i]);
1554
1555 mike 1.1 result.appendArray(paths);
1556 }
1557
1558 return result;
1559 }
1560
1561 Array<CIMObjectPath> CIMRepository::enumerateInstanceNamesForClass(
1562 const CIMNamespaceName& nameSpace,
1563 const CIMName& className)
1564 {
1565 Array<CIMObjectPath> result;
1566
1567 for (Uint32 i = 0; i < _rep->_rep.size(); i++)
1568 {
1569 if (_rep->_rep[i].first != nameSpace)
1570 continue;
1571
1572 CIMInstance& ci = _rep->_rep[i].second;
1573
1574 if (ci.getPath().getClassName() == className)
1575 result.append(ci.getPath());
1576 mike 1.1 }
1577
1578 return result;
1579 }
1580
1581 Array<CIMObject> CIMRepository::associators(
1582 const CIMNamespaceName& nameSpace,
1583 const CIMObjectPath& objectName,
1584 const CIMName& assocClass,
1585 const CIMName& resultClass,
1586 const String& role,
1587 const String& resultRole,
1588 Boolean includeQualifiers,
1589 Boolean includeClassOrigin,
1590 const CIMPropertyList& propertyList)
1591 {
1592 if (objectName.getKeyBindings().size() == 0)
1593 {
1594 return _associatorClasses(
1595 nameSpace,
1596 objectName.getClassName(),
1597 mike 1.1 assocClass,
1598 resultClass,
1599 role,
1600 resultRole,
1601 includeQualifiers,
1602 includeClassOrigin,
1603 propertyList);
1604 }
1605 else
1606 {
1607 Throw((CIM_ERR_NOT_SUPPORTED, "associators()"));
1608 return Array<CIMObject>();
1609 }
1610 }
1611
1612 Array<CIMObjectPath> CIMRepository::associatorNames(
1613 const CIMNamespaceName& nameSpace,
1614 const CIMObjectPath& objectName,
1615 const CIMName& assocClass,
1616 const CIMName& resultClass,
1617 const String& role,
1618 mike 1.1 const String& resultRole)
1619 {
1620 if (objectName.getKeyBindings().size() == 0)
1621 {
1622 return _associatorClassPaths(
1623 nameSpace,
1624 objectName.getClassName(),
1625 assocClass,
1626 resultClass,
1627 role,
1628 resultRole);
1629 }
1630 else
1631 {
1632 Throw((CIM_ERR_NOT_SUPPORTED, "associatorNames()"));
1633 return Array<CIMObjectPath>();
1634 }
1635 }
1636
1637 Array<CIMObject> CIMRepository::references(
1638 const CIMNamespaceName& nameSpace,
1639 mike 1.1 const CIMObjectPath& objectName,
1640 const CIMName& resultClass,
1641 const String& role,
1642 Boolean includeQualifiers,
1643 Boolean includeClassOrigin,
1644 const CIMPropertyList& propertyList)
1645 {
1646 if (objectName.getKeyBindings().size() == 0)
1647 {
1648 return _referenceClasses(
1649 nameSpace,
1650 objectName.getClassName(),
1651 resultClass,
1652 role,
1653 includeQualifiers,
1654 includeClassOrigin,
1655 propertyList);
1656 }
1657 else
1658 {
1659 Throw((CIM_ERR_NOT_SUPPORTED, "references()"));
1660 mike 1.1 return Array<CIMObject>();
1661 }
1662 }
1663
1664 Array<CIMObjectPath> CIMRepository::referenceNames(
1665 const CIMNamespaceName& nameSpace,
1666 const CIMObjectPath& objectName,
1667 const CIMName& resultClass,
1668 const String& role)
1669 {
1670 if (objectName.getKeyBindings().size() == 0)
1671 {
1672 return _referenceClassPaths(
1673 nameSpace,
1674 objectName.getClassName(),
1675 resultClass,
1676 role);
1677 }
1678 else
1679 {
1680 Throw((CIM_ERR_NOT_SUPPORTED, "referenceNames()"));
1681 mike 1.1 return Array<CIMObjectPath>();
1682 }
1683 }
1684
1685 CIMValue CIMRepository::getProperty(
1686 const CIMNamespaceName& nameSpace,
1687 const CIMObjectPath& instanceName,
1688 const CIMName& propertyName)
1689 {
1690 CIMInstance ci = getInstance(
1691 nameSpace, instanceName, false, true, true, CIMPropertyList());
1692
1693 Uint32 pos = ci.findProperty(propertyName);
1694
1695 if (pos == PEG_NOT_FOUND)
1696 {
1697 Throw((CIM_ERR_NO_SUCH_PROPERTY, "%s", *Str(propertyName)));
1698 }
1699
1700 return ci.getProperty(pos).getValue();
1701 }
1702 mike 1.1
1703 void CIMRepository::setProperty(
1704 const CIMNamespaceName& nameSpace,
1705 const CIMObjectPath& instanceName,
1706 const CIMName& propertyName,
1707 const CIMValue& newValue,
1708 const ContentLanguageList& contentLangs)
1709 {
1710 CIMInstance ci(instanceName.getClassName());
1711 ci.addProperty(CIMProperty(propertyName, newValue));
1712 ci.setPath(instanceName);
1713
1714 Array<CIMName> tmp;
1715 tmp.append(propertyName);
1716 CIMPropertyList properties(tmp);
1717
1718 modifyInstance(nameSpace, ci, false, properties, ContentLanguageList());
1719 }
1720
1721 CIMQualifierDecl CIMRepository::getQualifier(
1722 const CIMNamespaceName& nameSpace,
1723 mike 1.1 const CIMName& qualifierName)
1724 {
1725 return _getQualifier(nameSpace, qualifierName);
1726 }
1727
1728 void CIMRepository::setQualifier(
1729 const CIMNamespaceName& nameSpace,
1730 const CIMQualifierDecl& qualifierDecl,
1731 const ContentLanguageList& contentLangs)
1732 {
1733 Throw((CIM_ERR_NOT_SUPPORTED, "setQualifier()"));
1734 }
1735
1736 void CIMRepository::deleteQualifier(
1737 const CIMNamespaceName& nameSpace,
1738 const CIMName& qualifierName)
1739 {
1740 Throw((CIM_ERR_NOT_SUPPORTED, "deleteQualifier()"));
1741 }
1742
1743 Array<CIMQualifierDecl> CIMRepository::enumerateQualifiers(
1744 mike 1.1 const CIMNamespaceName& nameSpace)
1745 {
1746 return _enumerateQualifiers(nameSpace);
1747 }
1748
1749 void CIMRepository::createNameSpace(
1750 const CIMNamespaceName& nameSpace,
1751 const NameSpaceAttributes& attributes)
1752 {
1753 Throw((CIM_ERR_NOT_SUPPORTED, "createNameSpace()"));
1754 }
1755
1756 void CIMRepository::modifyNameSpace(
1757 const CIMNamespaceName& nameSpace,
1758 const NameSpaceAttributes& attributes)
1759 {
1760 Throw((CIM_ERR_NOT_SUPPORTED, "modifyNameSpace()"));
1761 }
1762
1763 Array<CIMNamespaceName> CIMRepository::enumerateNameSpaces() const
1764 {
1765 mike 1.1 return _enumerateNameSpaces();
1766 }
1767
1768 void CIMRepository::deleteNameSpace(
1769 const CIMNamespaceName& nameSpace)
1770 {
1771 Throw((CIM_ERR_NOT_SUPPORTED, "deleteNameSpace()"));
1772 }
1773
1774 Boolean CIMRepository::getNameSpaceAttributes(
1775 const CIMNamespaceName& nameSpace,
1776 NameSpaceAttributes& attributes)
1777 {
1778 attributes.clear();
1779 return false;
1780 }
1781
1782 Boolean CIMRepository::isDefaultInstanceProvider()
1783 {
1784 return true;
1785 }
1786 mike 1.1
1787 void CIMRepository::getSubClassNames(
1788 const CIMNamespaceName& nameSpace,
1789 const CIMName& className,
1790 Boolean deepInheritance,
1791 Array<CIMName>& subClassNames) const
1792 {
1793 _getSubClassNames(nameSpace, className, deepInheritance, subClassNames);
1794 }
1795
1796 void CIMRepository::getSuperClassNames(
1797 const CIMNamespaceName& nameSpace,
1798 const CIMName& className,
1799 Array<CIMName>& superClassNames) const
1800 {
1801 _getSuperClassNames(nameSpace, className, superClassNames);
1802 }
1803
1804 Boolean CIMRepository::isRemoteNameSpace(
1805 const CIMNamespaceName& nameSpace,
1806 String& remoteInfo)
1807 mike 1.1 {
1808 return false;
1809 }
1810
1811 #ifdef PEGASUS_DEBUG
1812 void CIMRepository::DisplayCacheStatistics()
1813 {
1814 }
1815 #endif
1816
1817 Uint32 CIMRepositoryRep::_findInstance(
1818 const CIMNamespaceName& nameSpace,
1819 const CIMObjectPath& instanceName)
1820 {
1821 for (Uint32 i = 0; i < _rep.size(); i++)
1822 {
1823 if (_rep[i].first == nameSpace &&
1824 _rep[i].second.getPath() == instanceName)
1825 {
1826 return i;
1827 }
1828 mike 1.1 }
1829
1830 return PEG_NOT_FOUND;
1831 }
1832
1833 void MRRInstallSaveCallback(
1834 void (*callback)(const Buffer& buffer, void* data),
1835 void * data)
1836 {
1837 _saveCallback = callback;
1838 _saveData = data;
1839 }
1840
1841 void MRRInstallLoadCallback(
1842 void (*callback)(Buffer& buffer, void* data),
1843 void * data)
1844 {
1845 _loadCallback = callback;
1846 _loadData = data;
1847 }
1848
1849 mike 1.1 void CIMRepositoryRep::_processSaveCallback()
1850 {
1851 if (!_saveCallback)
1852 return;
1853
1854 Buffer out;
1855
1856 for (Uint32 i = 0; i < _rep.size(); i++)
1857 {
1858 MRRSerializeNameSpace(out, _rep[i].first);
1859 MRRSerializeInstance(out, _rep[i].second);
1860 }
1861
1862 (*_saveCallback)(out, _saveData);
1863 }
1864
1865 void CIMRepositoryRep::_processLoadCallback()
1866 {
1867 if (!_loadCallback)
1868 return;
1869
1870 mike 1.1 Buffer in;
1871 (*_loadCallback)(in, _loadData);
1872 size_t pos = 0;
1873
1874 while (pos != in.size())
1875 {
1876 CIMNamespaceName nameSpace;
1877
1878 if (MRRDeserializeNameSpace(in, pos, nameSpace) != 0)
1879 return;
1880
1881 CIMInstance cimInstance;
1882
1883 if (MRRDeserializeInstance(in, pos, cimInstance) != 0)
1884 return;
1885
1886 _rep.append(NamespaceInstancePair(nameSpace, cimInstance));
1887 }
1888 }
1889
1890 Boolean MRRAddNameSpace(const MRRNameSpace* nameSpace)
1891 mike 1.1 {
1892 if (!nameSpace)
1893 return false;
1894
1895 if (_nameSpaceTableSize == _MAX_NAMESPACE_TABLE_SIZE)
1896 return false;
1897
1898 if (_findNameSpace(nameSpace->name))
1899 return false;
1900
1901 _nameSpaceTable[_nameSpaceTableSize++] = nameSpace;
1902
1903 return true;
1904 }
1905
1906 void MRRInstallInitializeCallback(
1907 void (*callback)(CIMRepository* repository, void * data),
1908 void *data)
1909 {
1910 _initializeCallback = callback;
1911 _initializeData = data;
1912 mike 1.1 }
1913
1914 //==============================================================================
1915 //
1916 // Non-locking forms of repository methods.
1917 //
1918 //==============================================================================
1919
1920 CIMClass CIMRepository::_getClass(
1921 const CIMNamespaceName& nameSpace,
1922 const CIMName& className,
1923 Boolean localOnly,
1924 Boolean includeQualifiers,
1925 Boolean includeClassOrigin,
1926 const CIMPropertyList& propertyList)
1927 {
1928 return getClass(nameSpace, className, localOnly, includeQualifiers,
1929 includeClassOrigin, propertyList);
1930 }
1931
1932 CIMInstance CIMRepository::_getInstance(
1933 mike 1.1 const CIMNamespaceName& nameSpace,
1934 const CIMObjectPath& instanceName,
1935 Boolean localOnly,
1936 Boolean includeQualifiers,
1937 Boolean includeClassOrigin,
|