1 mike 1.48 //%/////////////////////////////////////////////////////////////////////////////
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.48 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
25 // Modified By:
26 //
27 //%/////////////////////////////////////////////////////////////////////////////
28
29 #include <cctype>
30 #include <cstdio>
31 #include <fstream>
32 #include <Pegasus/Common/Pair.h>
33 #include <Pegasus/Common/Destroyer.h>
34 #include <Pegasus/Common/FileSystem.h>
35 #include <Pegasus/Common/Exception.h>
36 #include <Pegasus/Common/XmlReader.h>
37 #include <Pegasus/Common/XmlWriter.h>
38 #include <Pegasus/Common/DeclContext.h>
39 #include <Pegasus/Common/DeclContext.h>
40 #include <Pegasus/Common/System.h>
41 #include "CIMRepository.h"
42 #include "RepositoryDeclContext.h"
43 mike 1.48 #include "InstanceIndexFile.h"
44 #include "AssocInstTable.h"
45 #include "AssocClassTable.h"
46
47 #define INDENT_XML_FILES
48
49 PEGASUS_USING_STD;
50
51 PEGASUS_NAMESPACE_BEGIN
52
53 ////////////////////////////////////////////////////////////////////////////////
54 //
55 // _LoadObject()
56 //
57 // Loads objects (classes, instances, and qualifiers) from disk to
58 // memory objects.
59 //
60 ////////////////////////////////////////////////////////////////////////////////
61
62 template<class Object>
63 void _LoadObject(
64 mike 1.48 const String& path,
65 Object& object)
66 {
67 // Get the real path of the file:
68
69 String realPath;
70
71 if (!FileSystem::existsNoCase(path, realPath))
72 throw CannotOpenFile(path);
73
74 // Load file into memory:
75
76 Array<Sint8> data;
77 FileSystem::loadFileToMemory(data, realPath);
78 data.append('\0');
79
80 XmlParser parser((char*)data.getData());
81
82 XmlReader::getObject(parser, object);
83 }
84
85 mike 1.48 ////////////////////////////////////////////////////////////////////////////////
86 //
87 // _SaveObject()
88 //
89 // Saves objects (classes, instances, and qualifiers) from memory to
90 // disk files.
91 //
92 ////////////////////////////////////////////////////////////////////////////////
93
94 template<class Object>
95 void _SaveObject(const String& path, const Object& object)
96 {
97 Array<Sint8> out;
98 object.toXml(out);
99
100 ArrayDestroyer<char> destroyer(path.allocateCString());
101 PEGASUS_STD(ofstream) os(destroyer.getPointer() PEGASUS_IOS_BINARY);
102
103 if (!os)
104 throw CannotOpenFile(path);
105
106 mike 1.48 #ifdef INDENT_XML_FILES
107 out.append('\0');
108 XmlWriter::indentedPrint(os, out.getData(), 2);
109 #else
110 os.write((char*)out.getData(), out.size());
111 #endif
112 }
113
114 static String _MakeAssocInstPath(
115 const String& nameSpace,
116 const String& repositoryRoot)
117 {
118 String tmp = nameSpace;
119 tmp.translate('/', '#');
120 return String(Cat(repositoryRoot, "/", tmp, "/instances/associations"));
121 }
122
123 static String _MakeAssocClassPath(
124 const String& nameSpace,
125 const String& repositoryRoot)
126 {
127 mike 1.48 String tmp = nameSpace;
128 tmp.translate('/', '#');
129 return String(Cat(repositoryRoot, "/", tmp, "/classes/associations"));
130 }
131
132 ////////////////////////////////////////////////////////////////////////////////
133 //
134 // CIMRepository
135 //
136 // The following are not implemented:
137 //
138 // CIMRepository::setProperty()
139 // CIMRepository::getProperty()
140 // CIMRepository::modifyInstance()
141 // CIMRepository::execQuery()
142 // CIMRepository::execQuery()
143 // CIMRepository::associators()
144 // CIMRepository::associatorNames()
145 // CIMRepository::referencess()
146 // CIMRepository::referencesNames()
147 // CIMRepository::invokeMethod()
148 mike 1.48 //
149 // Note that invokeMethod() will not never implemented since it is not
150 // meaningful for a repository.
151 //
152 // ATTN: need to combine instances of each class into a common file to
153 // improve disk utilization (too many i-nodes in Unix).
154 //
155 // ATTN: make operations on files non-case-sensitive.
156 //
157 ////////////////////////////////////////////////////////////////////////////////
158
159 CIMRepository::CIMRepository(const String& repositoryRoot)
160 : _repositoryRoot(repositoryRoot), _nameSpaceManager(repositoryRoot)
161 {
162 _context = new RepositoryDeclContext(this);
163 }
164
165 CIMRepository::~CIMRepository()
166 {
167 delete _context;
168 }
169 mike 1.48
170 CIMClass CIMRepository::getClass(
171 const String& nameSpace,
172 const String& className,
173 Boolean localOnly,
174 Boolean includeQualifiers,
175 Boolean includeClassOrigin,
176 const Array<String>& propertyList)
177 {
178 // ATTN: localOnly, includeQualifiers, and includeClassOrigin are ignored
179 // for now.
180
181 String classFilePath;
182 classFilePath = _nameSpaceManager.getClassFilePath(nameSpace, className);
183
184 CIMClass cimClass;
185 _LoadObject(classFilePath, cimClass);
186
187 return cimClass;
188 }
189
190 mike 1.48 Boolean CIMRepository::_getInstanceIndex(
191 const String& nameSpace,
192 const CIMReference& instanceName,
193 String& className,
194 Uint32& index,
195 Boolean searchSuperClasses) const
196 {
197 // -- Get all descendent classes of this class:
198
199 className = instanceName.getClassName();
200
201 Array<String> classNames;
202 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
203 classNames.prepend(className);
204
205 // -- Get all superclasses of this one:
206
207 if (searchSuperClasses)
208 _nameSpaceManager.getSuperClassNames(nameSpace, className, classNames);
209
210 // -- Search each qualifying instance file for the instance:
211 mike 1.48
212 for (Uint32 i = 0; i < classNames.size(); i++)
213 {
214 CIMReference tmpInstanceName = instanceName;
215 tmpInstanceName.setClassName(classNames[i]);
216
217 // -- Lookup index of instance:
218
219 String path = _getIndexFilePath(nameSpace, classNames[i]);
220
221 if (InstanceIndexFile::lookup(path, tmpInstanceName, index))
222 {
223 className = classNames[i];
224 return true;
225 }
226 }
227
228 return false;
229 }
230
231 CIMInstance CIMRepository::getInstance(
232 mike 1.48 const String& nameSpace,
233 const CIMReference& instanceName,
234 Boolean localOnly,
235 Boolean includeQualifiers,
236 Boolean includeClassOrigin,
237 const Array<String>& propertyList)
238 {
239 // -- Get the index for this instance:
240
241 String className;
242 Uint32 index;
243
244 if (!_getInstanceIndex(nameSpace, instanceName, className, index))
245 {
246 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, "getInstance()");
247 }
248
249 // -- Load the instance from the file:
250
251 String path = _getInstanceFilePath(nameSpace, className, index);
252 CIMInstance cimInstance;
253 mike 1.48 _LoadObject(path, cimInstance);
254 return cimInstance;
255 }
256
257 void CIMRepository::deleteClass(
258 const String& nameSpace,
259 const String& className)
260 {
261 // -- Get the class and check to see if it is an association class:
262
263 CIMClass cimClass = getClass(nameSpace, className, false);
264 Boolean isAssociation = cimClass.isAssociation();
265
266 // -- Disallow deletion if class has instances:
267
268 String path = _getIndexFilePath(nameSpace, className);
269 String realPath;
270
271 if (FileSystem::existsNoCase(path, realPath))
272 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_CLASS_HAS_INSTANCES, className);
273
274 mike 1.48 // -- Delete the class (disallowed if there are subclasses):
275
276 _nameSpaceManager.deleteClass(nameSpace, className);
277
278 // -- Remove association:
279
280 if (isAssociation)
281 {
282 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
283
284 if (FileSystem::exists(assocFileName))
285 AssocClassTable::deleteAssociation(assocFileName, className);
286 }
287 }
288
289 void CIMRepository::deleteInstance(
290 const String& nameSpace,
291 const CIMReference& instanceName)
292 {
293 // -- Lookup index of entry from index file:
294
295 mike 1.48 String indexFilePath = _getIndexFilePath(
296 nameSpace, instanceName.getClassName());
297
298 Uint32 index;
299
300 if (!InstanceIndexFile::lookup(indexFilePath, instanceName, index))
301 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
302
303 // -- Attempt to remove the instance file:
304
305 String instanceFilePath = _getInstanceFilePath(
306 nameSpace, instanceName.getClassName(), index);
307
308 if (!FileSystem::removeFileNoCase(instanceFilePath))
309 {
310 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
311 "failed to remove file in CIMRepository::deleteInstance()");
312 }
313
314 // -- Remove entry from index file:
315
316 mike 1.48 InstanceIndexFile::remove(indexFilePath, instanceName);
317
318 // -- Delete index file if it is now empty (zero size):
319
320 Uint32 size;
321
322 if (!FileSystem::getFileSizeNoCase(indexFilePath, size))
323 {
324 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
325 "unexpected failure in CIMRepository::deleteInstance()");
326 }
327
328 if (size == 0 && !FileSystem::removeFileNoCase(indexFilePath))
329 {
330 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
331 "unexpected failure in CIMRepository::deleteInstance()");
332 }
333
334 // -- Remove it from the association table (if it is really association).
335 // -- We ignore the return value intentionally. If it is an association,
336 // -- true is returned. Otherwise, true is returned.
337 mike 1.48
338 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
339
340 if (FileSystem::exists(assocFileName))
341 AssocInstTable::deleteAssociation(assocFileName, instanceName);
342 }
343
344 void CIMRepository::_createAssocClassEntries(
345 const String& nameSpace,
346 const CIMConstClass& assocClass)
347 {
348 // Open input file:
349
350 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
351 ofstream os;
352
353 if (!OpenAppend(os, assocFileName))
354 throw CannotOpenFile(assocFileName);
355
356 // Get the association's class name:
357
358 mike 1.48 String assocClassName = assocClass.getClassName();
359
360 // For each property:
361
362 Uint32 n = assocClass.getPropertyCount();
363
364 for (Uint32 i = 0; i < n; i++)
365 {
366 CIMConstProperty fromProp = assocClass.getProperty(i);
367
368 if (fromProp.getType() == CIMType::REFERENCE)
369 {
370 for (Uint32 j = 0; j < n; j++)
371 {
372 CIMConstProperty toProp = assocClass.getProperty(j);
373
374 if (toProp.getType() == CIMType::REFERENCE &&
375 fromProp.getName() != toProp.getName())
376 {
377 String fromClassName = fromProp.getReferenceClassName();
378 String fromPropertyName = fromProp.getName();
379 mike 1.48 String toClassName = toProp.getReferenceClassName();
380 String toPropertyName = toProp.getName();
381
382 AssocClassTable::append(
383 os,
384 assocClassName,
385 fromClassName,
386 fromPropertyName,
387 toClassName,
388 toPropertyName);
389 }
390 }
391 }
392 }
393 }
394
395 void CIMRepository::createClass(
396 const String& nameSpace,
397 const CIMClass& newClass)
398 {
399 // -- Resolve the class:
400 mike 1.48 CIMClass cimClass(newClass);
401
402 cimClass.resolve(_context, nameSpace);
403
404 // -- If an association, populate associations file:
405
406 if (cimClass.isAssociation())
407 _createAssocClassEntries(nameSpace, cimClass);
408
409 // -- Create namespace manager entry:
410
411 String classFilePath;
412
413 _nameSpaceManager.createClass(nameSpace, cimClass.getClassName(),
414 cimClass.getSuperClassName(), classFilePath);
415
416 // -- Create the class file:
417
418 _SaveObject(classFilePath, cimClass);
419 }
420
421 mike 1.48 /*------------------------------------------------------------------------------
422
423 This routine does the following:
424
425 1. Creates two entries in the association file for each relationship
426 formed by this new assocation instance. A binary association
427 (one with two references) ties two instances together. Suppose
428 there are two instances: I1 and I2. Then two entries are created:
429
430 I2 -> I1
431 I1 -> I2
432
433 For a ternary relationship, six entries will be created. Suppose
434 there are three instances: I1, I2, and I3:
435
436 I1 -> I2
437 I1 -> I3
438 I2 -> I1
439 I2 -> I3
440 I3 -> I1
441 I3 -> I2
442 mike 1.48
443 So for an N-ary relationship, there will be 2*N entries created.
444
445 2. Verifies that the association instance refers to real objects.
446 (note that an association reference may refer to either an instance
447 or a class). Throws an exception if one of the references does not
448 refer to a valid object.
449
450 ------------------------------------------------------------------------------*/
451
452 void CIMRepository::_createAssocInstEntries(
453 const String& nameSpace,
454 const CIMConstClass& cimClass,
455 const CIMInstance& cimInstance,
456 const CIMReference& instanceName)
457 {
458 // Open input file:
459
460 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
461 ofstream os;
462
463 mike 1.48 if (!OpenAppend(os, assocFileName))
464 throw CannotOpenFile(assocFileName);
465
466 // Get the association's instance name and class name:
467
468 String assocInstanceName = instanceName.toString();
469 String assocClassName = instanceName.getClassName();
470
471 // For each property:
472
473 for (Uint32 i = 0, n = cimInstance.getPropertyCount(); i < n; i++)
474 {
475 CIMConstProperty fromProp = cimInstance.getProperty(i);
476
477 // If a reference property:
478
479 if (fromProp.getType() == CIMType::REFERENCE)
480 {
481 // For each property:
482
483 for (Uint32 j = 0, n = cimInstance.getPropertyCount(); j < n; j++)
484 mike 1.48 {
485 CIMConstProperty toProp = cimInstance.getProperty(j);
486
487 // If a reference property and not the same property:
488
489 if (toProp.getType() == CIMType::REFERENCE &&
490 fromProp.getName() != toProp.getName())
491 {
492 CIMReference fromRef;
493 fromProp.getValue().get(fromRef);
494
495 CIMReference toRef;
496 toProp.getValue().get(toRef);
497
498 String fromObjectName = fromRef.toString();
499 String fromClassName = fromRef.getClassName();
500 String fromPropertyName = fromProp.getName();
501 String toObjectName = toRef.toString();
502 String toClassName = toRef.getClassName();
503 String toPropertyName = toProp.getName();
504
505 mike 1.48 AssocInstTable::append(
506 os,
507 assocInstanceName,
508 assocClassName,
509 fromObjectName,
510 fromClassName,
511 fromPropertyName,
512 toObjectName,
513 toClassName,
514 toPropertyName);
515 }
516 }
517 }
518 }
519 }
520
521 void CIMRepository::createInstance(
522 const String& nameSpace,
523 const CIMInstance& newInstance)
524 {
525 // -- Resolve the instance (looks up class):
526 mike 1.48 CIMInstance cimInstance(newInstance);
527
528 CIMConstClass cimClass;
529 cimInstance.resolve(_context, nameSpace, cimClass);
530 CIMReference instanceName = cimInstance.getInstanceName(cimClass);
531
532 // -- Make sure the class has keys (otherwise it will be impossible to
533 // -- create the instance.
534
535 if (!cimClass.hasKeys())
536 {
537 String message = "class has no keys: ";
538 message += cimClass.getClassName();
539 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, message);
540 }
541
542 // -- Be sure instance does not already exist:
543
544 String className;
545 Uint32 dummyIndex;
546
547 mike 1.48 if (_getInstanceIndex(nameSpace, instanceName, className, dummyIndex, true))
548 {
549 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS, instanceName.toString());
550 }
551
552 // -- Handle if association:
553
554 if (cimClass.isAssociation())
555 {
556 _createAssocInstEntries(nameSpace,
557 cimClass, cimInstance, instanceName);
558 }
559
560 // -- Get common base (of instance file and index file):
561
562 String instanceFileBase = _nameSpaceManager.getInstanceFileBase(
563 nameSpace, cimInstance.getClassName());
564
565 // -- Make index file entry:
566
567 String indexFilePath = _getIndexFilePath(
568 mike 1.48 nameSpace, cimInstance.getClassName());
569 Uint32 index;
570
571 if (!InstanceIndexFile::insert(indexFilePath, instanceName, index))
572 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS, instanceName.toString());
573
574 // -- Save instance to file:
575
576 String instanceFilePath = _getInstanceFilePath(nameSpace,
577 cimInstance.getClassName(), index);
578
579 _SaveObject(instanceFilePath, cimInstance);
580 }
581
582 void CIMRepository::modifyClass(
583 const String& nameSpace,
584 const CIMClass& modifiedClass)
585 {
586 // -- Resolve the class:
587 CIMClass cimClass(modifiedClass);
588
589 mike 1.48 cimClass.resolve(_context, nameSpace);
590
591 // -- Check to see if it is okay to modify this class:
592
593 String classFilePath;
594
595 _nameSpaceManager.checkModify(nameSpace, cimClass.getClassName(),
596 cimClass.getSuperClassName(), classFilePath);
597
598 // -- Delete the old file containing the class:
599
600 if (!FileSystem::removeFileNoCase(classFilePath))
601 {
602 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
603 "failed to remove file in CIMRepository::modifyClass()");
604 }
605
606 // -- Create new class file:
607
608 _SaveObject(classFilePath, cimClass);
609 }
610 mike 1.48
611 void CIMRepository::modifyInstance(
612 const String& nameSpace,
613 const CIMInstance& modifiedInstance)
614 {
615 // -- Resolve the instance (looks up the class):
616 CIMInstance cimInstance(modifiedInstance);
617
618 CIMConstClass cimClass;
619 cimInstance.resolve(_context, nameSpace, cimClass);
620
621 // -- Lookup index of entry from index file:
622
623 CIMReference instanceName = cimInstance.getInstanceName(cimClass);
624
625 String indexFilePath = _getIndexFilePath(
626 nameSpace, instanceName.getClassName());
627
628 Uint32 index;
629
630 if (!InstanceIndexFile::lookup(indexFilePath, instanceName, index))
631 mike 1.48 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
632
633 // -- Attempt to remove the instance file:
634
635 String instanceFilePath = _getInstanceFilePath(
636 nameSpace, instanceName.getClassName(), index);
637
638 if (!FileSystem::removeFileNoCase(instanceFilePath))
639 {
640 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
641 "failed to remove file in CIMRepository::deleteInstance()");
642 }
643
644 // -- Save instance to file:
645
646 _SaveObject(instanceFilePath, cimInstance);
647 }
648
649 Array<CIMClass> CIMRepository::enumerateClasses(
650 const String& nameSpace,
651 const String& className,
652 mike 1.48 Boolean deepInheritance,
653 Boolean localOnly,
654 Boolean includeQualifiers,
655 Boolean includeClassOrigin)
656 {
657 Array<String> classNames;
658
659 _nameSpaceManager.getSubClassNames(
660 nameSpace, className, deepInheritance, classNames);
661
662 Array<CIMClass> result;
663
664 for (Uint32 i = 0; i < classNames.size(); i++)
665 {
666 result.append(getClass(nameSpace, classNames[i], localOnly,
667 includeQualifiers, includeClassOrigin));
668 }
669
670 return result;
671 }
672
673 mike 1.48 Array<String> CIMRepository::enumerateClassNames(
674 const String& nameSpace,
675 const String& className,
676 Boolean deepInheritance)
677 {
678 Array<String> classNames;
679
680 _nameSpaceManager.getSubClassNames(
681 nameSpace, className, deepInheritance, classNames);
682
683 return classNames;
684 return Array<String>();
685 }
686
687 Array<CIMInstance> CIMRepository::enumerateInstances(
688 const String& nameSpace,
689 const String& className,
690 Boolean deepInheritance,
691 Boolean localOnly,
692 Boolean includeQualifiers,
693 Boolean includeClassOrigin,
694 mike 1.48 const Array<String>& propertyList)
695 {
696 // -- Get all descendent classes of this class:
697
698 Array<String> classNames;
699 _nameSpaceManager.getSubClassNames(
700 nameSpace, className, true, classNames);
701 classNames.prepend(className);
702
703 // -- Search each qualifying instance file for the instance:
704
705 Array<CIMReference> instanceNames;
706 Array<Uint32> indices;
707 Array<CIMInstance> instances;
708 Uint32 start = 0;
709
710 for (Uint32 i = 0; i < classNames.size(); i++)
711 {
712 // -- Form the name of the class index file:
713
714 String path = _getIndexFilePath(nameSpace, classNames[i]);
715 mike 1.48
716 // Get all instance names for that class:
717
718 InstanceIndexFile::appendInstanceNamesTo(path, instanceNames, indices);
719 PEGASUS_ASSERT(instanceNames.size() == indices.size());
720
721 // -- Load up all the instances of this class:
722
723 for (Uint32 j = start; j < instanceNames.size(); j++)
724 {
725 String instanceFilePath = _getInstanceFilePath(
726 nameSpace, classNames[i], indices[i]);
727
728 CIMInstance tmpInstance;
729 _LoadObject(instanceFilePath, tmpInstance);
730 instances.append(tmpInstance);
731 }
732
733 start = instanceNames.size();
734 }
735
736 mike 1.48 return instances;
737 }
738
739 Array<CIMReference> CIMRepository::enumerateInstanceNames(
740 const String& nameSpace,
741 const String& className)
742 {
743 // -- Get all descendent classes of this class:
744
745 Array<String> classNames;
746 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
747 classNames.prepend(className);
748
749 // -- Search each qualifying instance file for the instance:
750
751 Array<CIMReference> instanceNames;
752 Array<Uint32> indices;
753
754 for (Uint32 i = 0; i < classNames.size(); i++)
755 {
756 // -- Form the name of the class index file:
757 mike 1.48
758 String path = _getIndexFilePath(nameSpace, classNames[i]);
759
760 // Get all instances for that class:
761
762 InstanceIndexFile::appendInstanceNamesTo(path, instanceNames, indices);
763 }
764
765 return instanceNames;
766 }
767
768 Array<CIMInstance> CIMRepository::execQuery(
769 const String& queryLanguage,
770 const String& query)
771 {
772 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, "execQuery()");
773
774 return Array<CIMInstance>();
775 }
776
777 Array<CIMObjectWithPath> CIMRepository::associators(
778 mike 1.48 const String& nameSpace,
779 const CIMReference& objectName,
780 const String& assocClass,
781 const String& resultClass,
782 const String& role,
783 const String& resultRole,
784 Boolean includeQualifiers,
785 Boolean includeClassOrigin,
786 const Array<String>& propertyList)
787 {
788 Array<CIMReference> names = associatorNames(
789 nameSpace,
790 objectName,
791 assocClass,
792 resultClass,
793 role,
794 resultRole);
795
796 Array<CIMObjectWithPath> result;
797
798 for (Uint32 i = 0, n = names.size(); i < n; i++)
799 mike 1.48 {
800 String tmpNameSpace = names[i].getNameSpace();
801
802 if (tmpNameSpace.size() == 0)
803 tmpNameSpace = nameSpace;
804
805 if (names[i].isClassName())
806 {
807 CIMReference tmpRef = names[i];
808 tmpRef.setHost(String());
809 tmpRef.setNameSpace(String());
810
811 CIMClass cimClass = getClass(
812 tmpNameSpace,
813 tmpRef.getClassName(),
814 false,
815 includeQualifiers,
816 includeClassOrigin,
817 propertyList);
818
819 CIMObject cimObject(cimClass);
820 mike 1.48 result.append(CIMObjectWithPath(names[i], cimObject));
821 }
822 else
823 {
824 CIMReference tmpRef = names[i];
825 tmpRef.setHost(String());
826 tmpRef.setNameSpace(String());
827
828 CIMInstance cimInstance = getInstance(
829 tmpNameSpace,
830 tmpRef,
831 false,
832 includeQualifiers,
833 includeClassOrigin,
834 propertyList);
835
836 CIMObject cimObject(cimInstance);
837 result.append(CIMObjectWithPath(names[i], cimObject));
838 }
839 }
840
841 mike 1.48 return result;
842 }
843
844 Array<CIMReference> CIMRepository::associatorNames(
845 const String& nameSpace,
846 const CIMReference& objectName,
847 const String& assocClass,
848 const String& resultClass,
849 const String& role,
850 const String& resultRole)
851 {
852 Array<String> associatorNames;
853
854 if (objectName.isClassName())
855 {
856 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
857
858 AssocClassTable::getAssociatorNames(
859 assocFileName,
860 objectName.toString(),
861 assocClass,
862 mike 1.48 resultClass,
863 role,
864 resultRole,
865 associatorNames);
866 }
867 else
868 {
869 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
870
871 AssocInstTable::getAssociatorNames(
872 assocFileName,
873 objectName.toString(),
874 assocClass,
875 resultClass,
876 role,
877 resultRole,
878 associatorNames);
879 }
880
881 Array<CIMReference> result;
882
883 mike 1.48 for (Uint32 i = 0, n = associatorNames.size(); i < n; i++)
884 {
885 CIMReference r = associatorNames[i];
886
887 if (r.getHost().size() == 0)
888 r.setHost(System::getHostName());
889
890 if (r.getNameSpace().size() == 0)
891 r.setNameSpace(nameSpace);
892
893 result.append(r);
894 }
895
896 return result;
897 }
898
899 Array<CIMObjectWithPath> CIMRepository::references(
900 const String& nameSpace,
901 const CIMReference& objectName,
902 const String& resultClass,
903 const String& role,
904 mike 1.48 Boolean includeQualifiers,
905 Boolean includeClassOrigin,
906 const Array<String>& propertyList)
907 {
908 Array<CIMReference> names = referenceNames(
909 nameSpace,
910 objectName,
911 resultClass,
912 role);
913
914 Array<CIMObjectWithPath> result;
915
916 for (Uint32 i = 0, n = names.size(); i < n; i++)
917 {
918 String tmpNameSpace = names[i].getNameSpace();
919
920 if (tmpNameSpace.size() == 0)
921 tmpNameSpace = nameSpace;
922
923 // ATTN: getInstance() should this be able to handle instance names
924 // with host names and namespaces?
925 mike 1.48
926 CIMReference tmpRef = names[i];
927 tmpRef.setHost(String());
928 tmpRef.setNameSpace(String());
929
930 if (objectName.isClassName())
931 {
932 CIMClass cimClass = getClass(
933 tmpNameSpace,
934 tmpRef.getClassName(),
935 false,
936 includeQualifiers,
937 includeClassOrigin,
938 propertyList);
939
940 result.append(CIMObjectWithPath(names[i], cimClass));
941 }
942 else
943 {
944 CIMInstance instance = getInstance(
945 tmpNameSpace,
946 mike 1.48 tmpRef,
947 false,
948 includeQualifiers,
949 includeClassOrigin,
950 propertyList);
951
952 result.append(CIMObjectWithPath(names[i], instance));
953 }
954 }
955
956 return result;
957 }
958
959 Array<CIMReference> CIMRepository::referenceNames(
960 const String& nameSpace,
961 const CIMReference& objectName,
962 const String& resultClass,
963 const String& role)
964 {
965 Array<String> tmpReferenceNames;
966
967 mike 1.48 if (objectName.isClassName())
968 {
969 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
970
971 if (!AssocClassTable::getReferenceNames(
972 assocFileName,
973 objectName.getClassName(),
974 resultClass,
975 role,
976 tmpReferenceNames))
977 {
978 // Ignore error! It's okay not to have references.
979 }
980 }
981 else
982 {
983 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
984
985 if (!AssocInstTable::getReferenceNames(
986 assocFileName,
987 objectName,
988 mike 1.48 resultClass,
989 role,
990 tmpReferenceNames))
991 {
992 // Ignore error! It's okay not to have references.
993 }
994 }
995
996 Array<CIMReference> result;
997
998 for (Uint32 i = 0, n = tmpReferenceNames.size(); i < n; i++)
999 {
1000 CIMReference r = tmpReferenceNames[i];
1001
1002 if (r.getHost().size() == 0)
1003 r.setHost(System::getHostName());
1004
1005 if (r.getNameSpace().size() == 0)
1006 r.setNameSpace(nameSpace);
1007
1008 result.append(r);
1009 mike 1.48 }
1010
1011 return result;
1012 }
1013
1014 CIMValue CIMRepository::getProperty(
1015 const String& nameSpace,
1016 const CIMReference& instanceName,
1017 const String& propertyName)
1018 {
1019 // -- Get the index for this instance:
1020
1021 String className;
1022 Uint32 index;
1023
1024 if (!_getInstanceIndex(nameSpace, instanceName, className, index))
1025 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, "getProperty()");
1026
1027 // -- Load the instance into memory:
1028
1029 String path = _getInstanceFilePath(nameSpace, className, index);
1030 mike 1.48 CIMInstance cimInstance;
1031 _LoadObject(path, cimInstance);
1032
1033 // -- Grab the property from the instance:
1034
1035 Uint32 pos = cimInstance.findProperty(propertyName);
1036
1037 if (pos == PEGASUS_NOT_FOUND)
1038 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NO_SUCH_PROPERTY, "getProperty()");
1039
1040 CIMProperty prop = cimInstance.getProperty(pos);
1041
1042 // -- Return the value:
1043
1044 return prop.getValue();
1045 }
1046
1047 void CIMRepository::setProperty(
1048 const String& nameSpace,
1049 const CIMReference& instanceName,
1050 const String& propertyName,
1051 mike 1.48 const CIMValue& newValue)
1052 {
1053 // -- Load the instance:
1054
1055 CIMInstance instance = getInstance(
1056 nameSpace, instanceName, false, true);
1057
1058 // -- Get the class:
1059
1060 CIMClass cimClass = getClass(nameSpace, instance.getClassName(),
1061 false, true);
1062
1063 // -- Save instance name:
1064
1065 CIMReference oldRef = instance.getInstanceName(cimClass);
1066
1067 // -- Modify the property (disallow if property is a key):
1068
1069 Uint32 pos = instance.findProperty(propertyName);
1070
1071 if (pos == PEGASUS_NOT_FOUND)
1072 mike 1.48 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NO_SUCH_PROPERTY, "setProperty()");
1073
1074 CIMProperty prop = instance.getProperty(pos);
1075
1076 prop.setValue(newValue);
1077
1078 // -- Disallow if instance name is changed by this operation (attempt
1079 // -- to modify a key property.
1080
1081 CIMReference newRef = instance.getInstanceName(cimClass);
1082
1083 if (oldRef != newRef)
1084 {
1085 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
1086 "setProperty(): attempted to modify a key property");
1087 }
1088
1089 // -- Modify the instance:
1090
1091 modifyInstance(nameSpace, instance);
1092 }
1093 mike 1.48
1094 CIMQualifierDecl CIMRepository::getQualifier(
1095 const String& nameSpace,
1096 const String& qualifierName)
1097 {
1098 // -- Get path of qualifier file:
1099
1100 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
1101 nameSpace, qualifierName);
1102
1103 // -- Load qualifier:
1104
1105 CIMQualifierDecl qualifierDecl;
1106
1107 try
1108 {
1109 _LoadObject(qualifierFilePath, qualifierDecl);
1110 }
1111 catch (CannotOpenFile&)
1112 {
1113 return CIMQualifierDecl();
1114 mike 1.48 }
1115
1116 return qualifierDecl;
1117 }
1118
1119 void CIMRepository::setQualifier(
1120 const String& nameSpace,
1121 const CIMQualifierDecl& qualifierDecl)
1122 {
1123 // -- Get path of qualifier file:
1124
1125 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
1126 nameSpace, qualifierDecl.getName());
1127
1128 // -- If qualifier alread exists, throw exception:
1129
1130 if (FileSystem::existsNoCase(qualifierFilePath))
1131 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS, qualifierDecl.getName());
1132
1133 // -- Save qualifier:
1134
1135 mike 1.48 _SaveObject(qualifierFilePath, qualifierDecl);
1136 }
1137
1138 void CIMRepository::deleteQualifier(
1139 const String& nameSpace,
1140 const String& qualifierName)
1141 {
1142 // -- Get path of qualifier file:
1143
1144 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
1145 nameSpace, qualifierName);
1146
1147 // -- Delete qualifier:
1148
1149 if (!FileSystem::removeFileNoCase(qualifierFilePath))
1150 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, qualifierName);
1151 }
1152
1153 Array<CIMQualifierDecl> CIMRepository::enumerateQualifiers(
1154 const String& nameSpace)
1155 {
1156 mike 1.48 String qualifiersRoot = _nameSpaceManager.getQualifiersRoot(nameSpace);
1157
1158 Array<String> qualifierNames;
1159
1160 if (!FileSystem::getDirectoryContents(qualifiersRoot, qualifierNames))
1161 {
1162 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
1163 "enumerateQualifiers(): internal error");
1164 }
1165
1166 Array<CIMQualifierDecl> qualifiers;
1167
1168 for (Uint32 i = 0; i < qualifierNames.size(); i++)
1169 {
1170 CIMQualifierDecl qualifier = getQualifier(nameSpace, qualifierNames[i]);
1171 qualifiers.append(qualifier);
1172 }
1173
1174 return qualifiers;
1175 }
1176
1177 mike 1.48 CIMValue CIMRepository::invokeMethod(
1178 const String& nameSpace,
1179 const CIMReference& instanceName,
1180 const String& methodName,
1181 const Array<CIMValue>& inParameters,
1182 Array<CIMValue>& outParameters)
1183 {
1184 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, "invokeMethod()");
1185 return CIMValue();
1186 }
1187
1188 void CIMRepository::createNameSpace(const String& nameSpace)
1189 {
1190 _nameSpaceManager.createNameSpace(nameSpace);
1191 }
1192
1193 Array<String> CIMRepository::enumerateNameSpaces() const
1194 {
1195 Array<String> nameSpaceNames;
1196 _nameSpaceManager.getNameSpaceNames(nameSpaceNames);
1197 return nameSpaceNames;
1198 mike 1.48 }
1199
1200 void CIMRepository::deleteNameSpace(const String& nameSpace)
1201 {
1202 _nameSpaceManager.deleteNameSpace(nameSpace);
1203 }
1204
1205 String CIMRepository::_getIndexFilePath(
1206 const String& nameSpace,
1207 const String& className) const
1208 {
1209 String tmp = _nameSpaceManager.getInstanceFileBase(nameSpace, className);
1210 tmp.append(".idx");
1211 return tmp;
1212 }
1213
1214 String CIMRepository::_getInstanceFilePath(
1215 const String& nameSpace,
1216 const String& className,
1217 Uint32 index) const
1218 {
1219 mike 1.48 String tmp = _nameSpaceManager.getInstanceFileBase(nameSpace, className);
1220 char extension[32];
1221 sprintf(extension, ".%d", index);
1222 tmp += extension;
1223 return tmp;
1224 }
1225
|