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 mike 1.51 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
26 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
27 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
28 mike 1.48 //
29 //%/////////////////////////////////////////////////////////////////////////////
30
|
31 mike 1.51 #include <Pegasus/Common/Config.h>
|
32 mike 1.48 #include <cctype>
33 #include <cstdio>
34 #include <fstream>
35 #include <Pegasus/Common/Pair.h>
36 #include <Pegasus/Common/Destroyer.h>
37 #include <Pegasus/Common/FileSystem.h>
38 #include <Pegasus/Common/Exception.h>
39 #include <Pegasus/Common/XmlReader.h>
40 #include <Pegasus/Common/XmlWriter.h>
41 #include <Pegasus/Common/DeclContext.h>
42 #include <Pegasus/Common/DeclContext.h>
43 #include <Pegasus/Common/System.h>
44 #include "CIMRepository.h"
45 #include "RepositoryDeclContext.h"
46 #include "InstanceIndexFile.h"
|
47 mike 1.51 #include "InstanceFile.h"
|
48 mike 1.48 #include "AssocInstTable.h"
49 #include "AssocClassTable.h"
50
51 #define INDENT_XML_FILES
52
53 PEGASUS_USING_STD;
54
55 PEGASUS_NAMESPACE_BEGIN
56
57 ////////////////////////////////////////////////////////////////////////////////
58 //
59 // _LoadObject()
60 //
|
61 mike 1.51 // Loads objects (classes and qualifiers) from disk to
62 // memory objects.
|
63 mike 1.48 //
64 ////////////////////////////////////////////////////////////////////////////////
65
66 template<class Object>
67 void _LoadObject(
68 const String& path,
69 Object& object)
70 {
71 // Get the real path of the file:
72
73 String realPath;
74
75 if (!FileSystem::existsNoCase(path, realPath))
|
76 mike 1.51 throw CannotOpenFile(path);
|
77 mike 1.48
78 // Load file into memory:
79
80 Array<Sint8> data;
81 FileSystem::loadFileToMemory(data, realPath);
82 data.append('\0');
83
84 XmlParser parser((char*)data.getData());
85
86 XmlReader::getObject(parser, object);
87 }
88
89 ////////////////////////////////////////////////////////////////////////////////
90 //
91 // _SaveObject()
92 //
|
93 mike 1.51 // Saves objects (classes and qualifiers) from memory to
94 // disk files.
|
95 mike 1.48 //
96 ////////////////////////////////////////////////////////////////////////////////
97
98 template<class Object>
99 void _SaveObject(const String& path, const Object& object)
100 {
101 Array<Sint8> out;
102 object.toXml(out);
103
104 ArrayDestroyer<char> destroyer(path.allocateCString());
105 PEGASUS_STD(ofstream) os(destroyer.getPointer() PEGASUS_IOS_BINARY);
106
107 if (!os)
|
108 mike 1.51 throw CannotOpenFile(path);
|
109 mike 1.48
110 #ifdef INDENT_XML_FILES
111 out.append('\0');
112 XmlWriter::indentedPrint(os, out.getData(), 2);
113 #else
114 os.write((char*)out.getData(), out.size());
115 #endif
116 }
117
118 static String _MakeAssocInstPath(
119 const String& nameSpace,
120 const String& repositoryRoot)
121 {
122 String tmp = nameSpace;
123 tmp.translate('/', '#');
124 return String(Cat(repositoryRoot, "/", tmp, "/instances/associations"));
125 }
126
127 static String _MakeAssocClassPath(
128 const String& nameSpace,
129 const String& repositoryRoot)
130 mike 1.48 {
131 String tmp = nameSpace;
132 tmp.translate('/', '#');
133 return String(Cat(repositoryRoot, "/", tmp, "/classes/associations"));
134 }
135
136 ////////////////////////////////////////////////////////////////////////////////
137 //
138 // CIMRepository
139 //
140 // The following are not implemented:
141 //
142 // CIMRepository::execQuery()
143 // CIMRepository::referencesNames()
144 // CIMRepository::invokeMethod()
145 //
146 // Note that invokeMethod() will not never implemented since it is not
147 // meaningful for a repository.
148 //
149 // ATTN: make operations on files non-case-sensitive.
150 //
151 mike 1.48 ////////////////////////////////////////////////////////////////////////////////
152
153 CIMRepository::CIMRepository(const String& repositoryRoot)
|
154 mike 1.51 : _repositoryRoot(repositoryRoot), _nameSpaceManager(repositoryRoot),
155 _lock()
|
156 mike 1.48 {
157 _context = new RepositoryDeclContext(this);
|
158 mike 1.51 _isDefaultInstanceProvider = (ConfigManager::getInstance()->getCurrentValue(
159 "repositoryIsDefaultInstanceProvider") == "true");
160 _providerName = ConfigManager::getInstance()->getCurrentValue(
161 "repositoryProviderName");
|
162 mike 1.48 }
163
164 CIMRepository::~CIMRepository()
165 {
166 delete _context;
167 }
168
|
169 mike 1.51
170 void CIMRepository::read_lock(void) throw(IPCException)
171 {
172 _lock.wait_read(pegasus_thread_self());
173 }
174
175 void CIMRepository::read_unlock(void)
176 {
177 _lock.unlock_read(pegasus_thread_self());
178 }
179
180 void CIMRepository::write_lock(void) throw(IPCException)
181 {
182 _lock.wait_write(pegasus_thread_self());
183 }
184
185 void CIMRepository::write_unlock(void)
186 {
187 _lock.unlock_write(pegasus_thread_self());
188 }
189
|
190 mike 1.48 CIMClass CIMRepository::getClass(
191 const String& nameSpace,
192 const String& className,
193 Boolean localOnly,
194 Boolean includeQualifiers,
195 Boolean includeClassOrigin,
|
196 mike 1.51 const CIMPropertyList& propertyList)
|
197 mike 1.48 {
198 // ATTN: localOnly, includeQualifiers, and includeClassOrigin are ignored
199 // for now.
200
|
201 mike 1.51
202
|
203 mike 1.48 String classFilePath;
204 classFilePath = _nameSpaceManager.getClassFilePath(nameSpace, className);
205
206 CIMClass cimClass;
|
207 mike 1.51
208 try
209 {
210 _LoadObject(classFilePath, cimClass);
211 }
212 catch (Exception & e)
213 {
214 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, className);
215 }
|
216 mike 1.48
217 return cimClass;
218 }
219
|
220 mike 1.51 //----------------------------------------------------------------------
221 //
222 // _getInstanceIndex()
223 //
224 // Returns the index (or byte location) and size of the instance
225 // record in the instance file for a given instance. Returns false
226 // if the instance cannot be found.
227 //
228 //----------------------------------------------------------------------
229
|
230 mike 1.48 Boolean CIMRepository::_getInstanceIndex(
231 const String& nameSpace,
232 const CIMReference& instanceName,
233 String& className,
|
234 mike 1.51 Uint32& size,
|
235 mike 1.48 Uint32& index,
236 Boolean searchSuperClasses) const
237 {
238 // -- Get all descendent classes of this class:
239
|
240 mike 1.51
|
241 mike 1.48 className = instanceName.getClassName();
242
243 Array<String> classNames;
244 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
245 classNames.prepend(className);
246
247 // -- Get all superclasses of this one:
248
249 if (searchSuperClasses)
|
250 mike 1.51 _nameSpaceManager.getSuperClassNames(nameSpace, className, classNames);
|
251 mike 1.48
|
252 mike 1.51 // -- Get instance names from each qualifying instance file for the class
|
253 mike 1.48
254 for (Uint32 i = 0; i < classNames.size(); i++)
255 {
|
256 mike 1.51 CIMReference tmpInstanceName = instanceName;
257 tmpInstanceName.setClassName(classNames[i]);
|
258 mike 1.48
|
259 mike 1.51 // -- Lookup index of instance:
|
260 mike 1.48
|
261 mike 1.51 String path = _getIndexFilePath(nameSpace, classNames[i]);
|
262 mike 1.48
|
263 mike 1.51 if (InstanceIndexFile::lookup(path, tmpInstanceName, size, index))
264 {
265 className = classNames[i];
266 return true;
267 }
|
268 mike 1.48 }
269
270 return false;
271 }
272
273 CIMInstance CIMRepository::getInstance(
274 const String& nameSpace,
275 const CIMReference& instanceName,
276 Boolean localOnly,
277 Boolean includeQualifiers,
278 Boolean includeClassOrigin,
|
279 mike 1.51 const CIMPropertyList& propertyList)
|
280 mike 1.48 {
281 // -- Get the index for this instance:
282
283 String className;
284 Uint32 index;
|
285 mike 1.51 Uint32 size;
286
|
287 mike 1.48
|
288 mike 1.51 if (!_getInstanceIndex(nameSpace, instanceName, className, size, index))
|
289 mike 1.48 {
|
290 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
291 mike 1.48 }
292
|
293 mike 1.51 // -- Load the instance from file:
|
294 mike 1.48
|
295 mike 1.51 String path = _getInstanceFilePath(nameSpace, className);
|
296 mike 1.48 CIMInstance cimInstance;
|
297 mike 1.51 if (!_loadInstance(path, cimInstance, index, size))
298 {
299 throw CannotOpenFile(path);
300 }
301
|
302 mike 1.48 return cimInstance;
303 }
304
305 void CIMRepository::deleteClass(
306 const String& nameSpace,
307 const String& className)
308 {
309 // -- Get the class and check to see if it is an association class:
310
|
311 mike 1.51
|
312 mike 1.48 CIMClass cimClass = getClass(nameSpace, className, false);
313 Boolean isAssociation = cimClass.isAssociation();
314
315 // -- Disallow deletion if class has instances:
316
317 String path = _getIndexFilePath(nameSpace, className);
318 String realPath;
319
320 if (FileSystem::existsNoCase(path, realPath))
|
321 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_CLASS_HAS_INSTANCES, className);
|
322 mike 1.48
323 // -- Delete the class (disallowed if there are subclasses):
324
325 _nameSpaceManager.deleteClass(nameSpace, className);
326
327 // -- Remove association:
328
329 if (isAssociation)
330 {
|
331 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
332 mike 1.48
|
333 mike 1.51 if (FileSystem::exists(assocFileName))
334 AssocClassTable::deleteAssociation(assocFileName, className);
|
335 mike 1.48 }
336 }
337
338 void CIMRepository::deleteInstance(
339 const String& nameSpace,
340 const CIMReference& instanceName)
341 {
|
342 mike 1.51
343 String errMessage;
344
345 // -- Lookup instance from the index file:
|
346 mike 1.48
347 String indexFilePath = _getIndexFilePath(
|
348 mike 1.51 nameSpace, instanceName.getClassName());
|
349 mike 1.48
350 Uint32 index;
|
351 mike 1.51 Uint32 size;
|
352 mike 1.48
|
353 mike 1.51 if (!InstanceIndexFile::lookup(indexFilePath, instanceName, size, index))
354 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
355 mike 1.48
|
356 mike 1.51 // -- Remove entry from index file:
|
357 mike 1.48
|
358 mike 1.51 if (!InstanceIndexFile::remove(indexFilePath, instanceName))
|
359 mike 1.48 {
|
360 mike 1.51 errMessage.append("Failed to delete instance ");
361 errMessage.append(instanceName.toString());
362 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
363 mike 1.48 }
364
|
365 mike 1.51 // -- Remove the instance from the instance file:
|
366 mike 1.48
|
367 mike 1.51 String instanceFilePath = _getInstanceFilePath(
368 nameSpace, instanceName.getClassName());
|
369 mike 1.48
|
370 mike 1.51 if (!InstanceFile::removeInstance(instanceFilePath, size, index))
|
371 mike 1.48 {
|
372 mike 1.51 errMessage.append("Failed to delete instance ");
373 errMessage.append(instanceName.toString());
374 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
375 mike 1.48 }
376
|
377 mike 1.51 // -- Rename the temporary index and instance files back to the original:
378
379 if (!_renameTempInstanceAndIndexFiles(indexFilePath, instanceFilePath))
|
380 mike 1.48 {
|
381 mike 1.51 errMessage.append("Unexpected error occurred while deleting instance ");
382 errMessage.append(instanceName.toString());
383 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
384 mike 1.48 }
385
386 // -- Remove it from the association table (if it is really association).
387 // -- We ignore the return value intentionally. If it is an association,
388 // -- true is returned. Otherwise, true is returned.
389
390 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
391
392 if (FileSystem::exists(assocFileName))
|
393 mike 1.51 AssocInstTable::deleteAssociation(assocFileName, instanceName);
|
394 mike 1.48 }
395
396 void CIMRepository::_createAssocClassEntries(
397 const String& nameSpace,
398 const CIMConstClass& assocClass)
399 {
400 // Open input file:
401
|
402 mike 1.51
|
403 mike 1.48 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
404 ofstream os;
405
406 if (!OpenAppend(os, assocFileName))
|
407 mike 1.51 throw CannotOpenFile(assocFileName);
|
408 mike 1.48
409 // Get the association's class name:
410
411 String assocClassName = assocClass.getClassName();
412
413 // For each property:
414
415 Uint32 n = assocClass.getPropertyCount();
416
417 for (Uint32 i = 0; i < n; i++)
418 {
|
419 mike 1.51 CIMConstProperty fromProp = assocClass.getProperty(i);
|
420 mike 1.48
|
421 mike 1.51 if (fromProp.getType() == CIMType::REFERENCE)
422 {
423 for (Uint32 j = 0; j < n; j++)
424 {
425 CIMConstProperty toProp = assocClass.getProperty(j);
426
427 if (toProp.getType() == CIMType::REFERENCE &&
428 fromProp.getName() != toProp.getName())
429 {
430 String fromClassName = fromProp.getReferenceClassName();
431 String fromPropertyName = fromProp.getName();
432 String toClassName = toProp.getReferenceClassName();
433 String toPropertyName = toProp.getName();
434
435 AssocClassTable::append(
436 os,
437 assocClassName,
438 fromClassName,
439 fromPropertyName,
440 toClassName,
441 toPropertyName);
442 mike 1.51 }
443 }
444 }
|
445 mike 1.48 }
446 }
447
448 void CIMRepository::createClass(
449 const String& nameSpace,
450 const CIMClass& newClass)
451 {
|
452 mike 1.51
453
|
454 mike 1.48 // -- Resolve the class:
|
455 mike 1.51 CIMClass cimClass(newClass);
456
|
457 mike 1.48 cimClass.resolve(_context, nameSpace);
458
459 // -- If an association, populate associations file:
460
461 if (cimClass.isAssociation())
|
462 mike 1.51 _createAssocClassEntries(nameSpace, cimClass);
|
463 mike 1.48
464 // -- Create namespace manager entry:
465
466 String classFilePath;
467
468 _nameSpaceManager.createClass(nameSpace, cimClass.getClassName(),
|
469 mike 1.51 cimClass.getSuperClassName(), classFilePath);
|
470 mike 1.48
471 // -- Create the class file:
472
473 _SaveObject(classFilePath, cimClass);
474 }
475
476 /*------------------------------------------------------------------------------
477
478 This routine does the following:
479
|
480 mike 1.51 1. Creates two entries in the association file for each relationship
481 formed by this new assocation instance. A binary association
482 (one with two references) ties two instances together. Suppose
483 there are two instances: I1 and I2. Then two entries are created:
484
485 I2 -> I1
486 I1 -> I2
487
488 For a ternary relationship, six entries will be created. Suppose
489 there are three instances: I1, I2, and I3:
490
491 I1 -> I2
492 I1 -> I3
493 I2 -> I1
494 I2 -> I3
495 I3 -> I1
496 I3 -> I2
497
498 So for an N-ary relationship, there will be 2*N entries created.
499
500 2. Verifies that the association instance refers to real objects.
501 mike 1.51 (note that an association reference may refer to either an instance
502 or a class). Throws an exception if one of the references does not
503 refer to a valid object.
|
504 mike 1.48
505 ------------------------------------------------------------------------------*/
506
507 void CIMRepository::_createAssocInstEntries(
508 const String& nameSpace,
509 const CIMConstClass& cimClass,
510 const CIMInstance& cimInstance,
511 const CIMReference& instanceName)
512 {
513 // Open input file:
514
|
515 mike 1.51
|
516 mike 1.48 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
517 ofstream os;
518
519 if (!OpenAppend(os, assocFileName))
|
520 mike 1.51 throw CannotOpenFile(assocFileName);
|
521 mike 1.48
522 // Get the association's instance name and class name:
523
524 String assocInstanceName = instanceName.toString();
525 String assocClassName = instanceName.getClassName();
526
527 // For each property:
528
529 for (Uint32 i = 0, n = cimInstance.getPropertyCount(); i < n; i++)
530 {
|
531 mike 1.51 CIMConstProperty fromProp = cimInstance.getProperty(i);
|
532 mike 1.48
|
533 mike 1.51 // If a reference property:
|
534 mike 1.48
|
535 mike 1.51 if (fromProp.getType() == CIMType::REFERENCE)
536 {
537 // For each property:
538
539 for (Uint32 j = 0, n = cimInstance.getPropertyCount(); j < n; j++)
540 {
541 CIMConstProperty toProp = cimInstance.getProperty(j);
542
543 // If a reference property and not the same property:
544
545 if (toProp.getType() == CIMType::REFERENCE &&
546 fromProp.getName() != toProp.getName())
547 {
548 CIMReference fromRef;
549 fromProp.getValue().get(fromRef);
550
551 CIMReference toRef;
552 toProp.getValue().get(toRef);
553
554 String fromObjectName = fromRef.toString();
555 String fromClassName = fromRef.getClassName();
556 mike 1.51 String fromPropertyName = fromProp.getName();
557 String toObjectName = toRef.toString();
558 String toClassName = toRef.getClassName();
559 String toPropertyName = toProp.getName();
560
561 AssocInstTable::append(
562 os,
563 assocInstanceName,
564 assocClassName,
565 fromObjectName,
566 fromClassName,
567 fromPropertyName,
568 toObjectName,
569 toClassName,
570 toPropertyName);
571 }
572 }
573 }
|
574 mike 1.48 }
575 }
576
|
577 mike 1.51 CIMReference CIMRepository::createInstance(
|
578 mike 1.48 const String& nameSpace,
579 const CIMInstance& newInstance)
580 {
|
581 mike 1.51
582 String errMessage;
583
|
584 mike 1.48 // -- Resolve the instance (looks up class):
|
585 mike 1.51 CIMInstance cimInstance(newInstance);
|
586 mike 1.48
587 CIMConstClass cimClass;
588 cimInstance.resolve(_context, nameSpace, cimClass);
589 CIMReference instanceName = cimInstance.getInstanceName(cimClass);
590
591 // -- Make sure the class has keys (otherwise it will be impossible to
592 // -- create the instance.
593
594 if (!cimClass.hasKeys())
595 {
|
596 mike 1.51 errMessage = "class has no keys: ";
597 errMessage += cimClass.getClassName();
598 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
599 mike 1.48 }
600
601 // -- Be sure instance does not already exist:
602
603 String className;
604 Uint32 dummyIndex;
|
605 mike 1.51 Uint32 dummySize;
|
606 mike 1.48
|
607 mike 1.51 if (_getInstanceIndex(nameSpace, instanceName, className, dummySize,
608 dummyIndex, true))
|
609 mike 1.48 {
|
610 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS,
611 instanceName.toString());
|
612 mike 1.48 }
613
614 // -- Handle if association:
615
616 if (cimClass.isAssociation())
617 {
|
618 mike 1.51 _createAssocInstEntries(nameSpace,
619 cimClass, cimInstance, instanceName);
|
620 mike 1.48 }
621
|
622 mike 1.51 // -- Get instance file path:
|
623 mike 1.48
|
624 mike 1.51 String instanceFilePath = _getInstanceFilePath(nameSpace,
625 cimInstance.getClassName());
626
627 // -- Save instance to file:
628
629 Uint32 index;
630 Uint32 size;
631 if (!_saveInstance(instanceFilePath, cimInstance, index, size))
632 {
633 errMessage.append("Failed to create instance ");
634 errMessage.append(instanceName.toString());
635 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
636 }
|
637 mike 1.48
638 // -- Make index file entry:
639
640 String indexFilePath = _getIndexFilePath(
|
641 mike 1.51 nameSpace, cimInstance.getClassName());
|
642 mike 1.48
|
643 mike 1.51 if (!InstanceIndexFile::insert(indexFilePath, instanceName, size, index))
644 {
645 errMessage.append("Failed to create instance ");
646 errMessage.append(instanceName.toString());
647 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
648 }
|
649 mike 1.48
|
650 mike 1.51 // -- Rename the temporary index and instance files back to the original
|
651 mike 1.48
|
652 mike 1.51 if (!_renameTempInstanceAndIndexFiles(indexFilePath, instanceFilePath))
653 {
654 errMessage.append("Unexpected error occurred while creating instance ");
655 errMessage.append(instanceName.toString());
656 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
657 }
658 return (instanceName);
|
659 mike 1.48 }
660
661 void CIMRepository::modifyClass(
662 const String& nameSpace,
663 const CIMClass& modifiedClass)
664 {
|
665 mike 1.51
666
|
667 mike 1.48 // -- Resolve the class:
|
668 mike 1.51 CIMClass cimClass(modifiedClass);
|
669 mike 1.48
670 cimClass.resolve(_context, nameSpace);
671
672 // -- Check to see if it is okay to modify this class:
673
674 String classFilePath;
675
676 _nameSpaceManager.checkModify(nameSpace, cimClass.getClassName(),
|
677 mike 1.51 cimClass.getSuperClassName(), classFilePath);
|
678 mike 1.48
679 // -- Delete the old file containing the class:
680
681 if (!FileSystem::removeFileNoCase(classFilePath))
682 {
|
683 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
684 "failed to remove file in CIMRepository::modifyClass()");
|
685 mike 1.48 }
686
687 // -- Create new class file:
688
689 _SaveObject(classFilePath, cimClass);
690 }
691
692 void CIMRepository::modifyInstance(
693 const String& nameSpace,
|
694 mike 1.51 const CIMNamedInstance& modifiedInstance,
695 Boolean includeQualifiers,
696 const CIMPropertyList& propertyList)
|
697 mike 1.48 {
|
698 mike 1.51
699
700 String errMessage;
701 CIMInstance cimInstance; // The instance that replaces the original
702
703 if (propertyList.isNull())
704 {
705 //
706 // Replace all the properties in the instance
707 //
708 if (includeQualifiers)
709 {
710 //
711 // Replace the entire instance with the given instance
712 // (this is the default behavior)
713 //
714 cimInstance = modifiedInstance.getInstance();
715 }
716 else
717 {
718 //
719 mike 1.51 // Replace all the properties in the instance, but keep the
720 // original qualifiers on the instance and on the properties
721 //
722
723 cimInstance = getInstance(nameSpace,
724 modifiedInstance.getInstanceName(), false, true);
725 CIMInstance newInstance(
726 modifiedInstance.getInstanceName().getClassName());
727 CIMInstance givenInstance = modifiedInstance.getInstance();
728
729 //
730 // Copy over the original instance qualifiers
731 //
732 for (Uint32 i=0; i<cimInstance.getQualifierCount(); i++)
733 {
734 newInstance.addQualifier(cimInstance.getQualifier(i));
735 }
736
737 //
738 // Loop through the properties replacing each property in the
739 // original with a new value, but keeping the original qualifiers
740 mike 1.51 //
741 for (Uint32 i=0; i<givenInstance.getPropertyCount(); i++)
742 {
743 // Copy the given property value (not qualifiers)
744 CIMProperty givenProperty = givenInstance.getProperty(i);
745 CIMProperty newProperty(
746 givenProperty.getName(),
747 givenProperty.getValue(),
748 givenProperty.getArraySize(),
749 givenProperty.getReferenceClassName(),
750 givenProperty.getClassOrigin(),
751 givenProperty.getPropagated());
752
753 // Copy the original property qualifiers
754 Uint32 origPos =
755 cimInstance.findProperty(newProperty.getName());
756 if (origPos != PEG_NOT_FOUND)
757 {
758 CIMProperty origProperty = cimInstance.getProperty(origPos);
759 for (Uint32 j=0; j<origProperty.getQualifierCount(); j++)
760 {
761 mike 1.51 newProperty.addQualifier(origProperty.getQualifier(i));
762 }
763 }
764
765 // Add the newly constructed property to the new instance
766 newInstance.addProperty(newProperty);
767 }
768
769 // Use the newly merged instance to replace the original instance
770 cimInstance = newInstance;
771 }
772 }
773 else
774 {
775 //
776 // Replace only the properties specified in the given instance
777 //
778
779 cimInstance = getInstance(nameSpace,
780 modifiedInstance.getInstanceName(), false, true);
781 CIMInstance givenInstance = modifiedInstance.getInstance();
782 mike 1.51
783 // NOTE: Instance qualifiers are not changed when a property list
784 // is specified. Property qualifiers are replaced with the
785 // corresponding property values.
786
787 //
788 // Loop through the propertyList replacing each property in the original
789 //
790 for (Uint32 i=0; i<propertyList.getNumProperties(); i++)
791 {
792 Uint32 origPropPos =
793 cimInstance.findProperty(propertyList.getPropertyName(i));
794 if (origPropPos != PEG_NOT_FOUND)
795 {
796 // Case: Property set in original
797 CIMProperty origProperty =
798 cimInstance.getProperty(origPropPos);
799
800 // Get the given property value
801 Uint32 givenPropPos =
802 givenInstance.findProperty(propertyList.getPropertyName(i));
803 mike 1.51 if (givenPropPos != PEG_NOT_FOUND)
804 {
805 // Case: Property set in original and given
806 CIMProperty givenProperty =
807 givenInstance.getProperty(givenPropPos);
808
809 // Copy over the property from the given to the original
810 if (includeQualifiers)
811 {
812 // Case: Total property replacement
813 cimInstance.removeProperty(origPropPos);
814 cimInstance.addProperty(givenProperty);
815 }
816 else
817 {
818 // Case: Replace only the property value (not quals)
819 origProperty.setValue(givenProperty.getValue());
820 cimInstance.removeProperty(origPropPos);
821 cimInstance.addProperty(origProperty);
822 }
823 }
824 mike 1.51 else
825 {
826 // Case: Property set in original and not in given
827 // Just remove the property (set to null)
828 cimInstance.removeProperty(origPropPos);
829 }
830 }
831 else
832 {
833 // Case: Property not set in original
834
835 // Get the given property value
836 Uint32 givenPropPos =
837 givenInstance.findProperty(propertyList.getPropertyName(i));
838 if (givenPropPos != PEG_NOT_FOUND)
839 {
840 // Case: Property set in given and not in original
841 CIMProperty givenProperty =
842 givenInstance.getProperty(givenPropPos);
843
844 // Copy over the property from the given to the original
845 mike 1.51 if (includeQualifiers)
846 {
847 // Case: Total property copy
848 cimInstance.addProperty(givenProperty);
849 }
850 else
851 {
852 // Case: Copy only the property value (not qualifiers)
853 CIMProperty newProperty(
854 givenProperty.getName(),
855 givenProperty.getValue(),
856 givenProperty.getArraySize(),
857 givenProperty.getReferenceClassName(),
858 givenProperty.getClassOrigin(),
859 givenProperty.getPropagated());
860 cimInstance.addProperty(newProperty);
861 }
862 }
863 else
864 {
865 // Case: Property not set in original or in given
866 mike 1.51
867 // Nothing to do; just make sure the property name is valid
868 // ATTN: This is not the most efficient solution
869 CIMClass cimClass = getClass(
870 nameSpace, cimInstance.getClassName(), false);
871 if (!cimClass.existsProperty(
872 propertyList.getPropertyName(i)))
873 {
874 // ATTN: This exception may be returned by setProperty
875 throw PEGASUS_CIM_EXCEPTION(
876 CIM_ERR_NO_SUCH_PROPERTY, "modifyInstance()");
877 }
878 }
879 }
880 }
881 }
882
|
883 mike 1.48 // -- Resolve the instance (looks up the class):
884
885 CIMConstClass cimClass;
886 cimInstance.resolve(_context, nameSpace, cimClass);
887
|
888 mike 1.51 CIMReference instanceName = cimInstance.getInstanceName(cimClass);
889
890 // -- Disallow if instance name is changed by this operation (attempt
891 // -- to modify a key property.
892
893 if (instanceName != modifiedInstance.getInstanceName())
894 {
895 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
896 "Attempted to modify a key property");
897 }
898
|
899 mike 1.48 // -- Lookup index of entry from index file:
900
901 String indexFilePath = _getIndexFilePath(
|
902 mike 1.51 nameSpace, instanceName.getClassName());
|
903 mike 1.48
|
904 mike 1.51 Uint32 oldSize;
905 Uint32 oldIndex;
906 Uint32 newSize;
907 Uint32 newIndex;
|
908 mike 1.48
|
909 mike 1.51 if (!InstanceIndexFile::lookup(indexFilePath, instanceName, oldSize,
910 oldIndex))
911 {
912 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
913 }
|
914 mike 1.48
|
915 mike 1.51 // -- modify the instance file
|
916 mike 1.48
917 String instanceFilePath = _getInstanceFilePath(
|
918 mike 1.51 nameSpace, instanceName.getClassName());
|
919 mike 1.48
|
920 mike 1.51 if (!_modifyInstance(instanceFilePath, cimInstance, oldIndex, oldSize,
921 newIndex, newSize))
|
922 mike 1.48 {
|
923 mike 1.51 errMessage.append("Failed to modify instance ");
924 errMessage.append(instanceName.toString());
925 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
926 mike 1.48 }
927
|
928 mike 1.51 // -- modify the instance index file
929
930 if (!InstanceIndexFile::modify(indexFilePath, instanceName, newSize,
931 newIndex))
932 {
933 errMessage.append("Failed to modify instance ");
934 errMessage.append(instanceName.toString());
935 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
936 }
937
938 // -- Rename the temporary index and instance files back to the original
|
939 mike 1.48
|
940 mike 1.51 if (!_renameTempInstanceAndIndexFiles(indexFilePath, instanceFilePath))
941 {
942 errMessage.append("Unexpected error occurred while modifying instance ");
943 errMessage.append(instanceName.toString());
944 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
945 }
|
946 mike 1.48 }
947
948 Array<CIMClass> CIMRepository::enumerateClasses(
949 const String& nameSpace,
950 const String& className,
951 Boolean deepInheritance,
952 Boolean localOnly,
953 Boolean includeQualifiers,
954 Boolean includeClassOrigin)
955 {
|
956 mike 1.51
957
|
958 mike 1.48 Array<String> classNames;
959
960 _nameSpaceManager.getSubClassNames(
|
961 mike 1.51 nameSpace, className, deepInheritance, classNames);
|
962 mike 1.48
963 Array<CIMClass> result;
964
965 for (Uint32 i = 0; i < classNames.size(); i++)
966 {
|
967 mike 1.51 result.append(getClass(nameSpace, classNames[i], localOnly,
968 includeQualifiers, includeClassOrigin));
|
969 mike 1.48 }
970
971 return result;
972 }
973
974 Array<String> CIMRepository::enumerateClassNames(
975 const String& nameSpace,
976 const String& className,
977 Boolean deepInheritance)
978 {
|
979 mike 1.51
980
981
|
982 mike 1.48 Array<String> classNames;
983
984 _nameSpaceManager.getSubClassNames(
|
985 mike 1.51 nameSpace, className, deepInheritance, classNames);
|
986 mike 1.48
987 return classNames;
988 }
989
|
990 mike 1.51 Array<CIMNamedInstance> CIMRepository::enumerateInstances(
|
991 mike 1.48 const String& nameSpace,
992 const String& className,
993 Boolean deepInheritance,
994 Boolean localOnly,
995 Boolean includeQualifiers,
996 Boolean includeClassOrigin,
|
997 mike 1.51 const CIMPropertyList& propertyList)
|
998 mike 1.48 {
|
999 mike 1.51
1000
1001
|
1002 mike 1.48 // -- Get all descendent classes of this class:
1003
1004 Array<String> classNames;
|
1005 mike 1.51 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
|
1006 mike 1.48 classNames.prepend(className);
1007
|
1008 mike 1.51 // -- Get all instances for this class and all its descendent classes
|
1009 mike 1.48
|
1010 mike 1.51 Array<CIMNamedInstance> namedInstances;
|
1011 mike 1.48
1012 for (Uint32 i = 0; i < classNames.size(); i++)
1013 {
|
1014 mike 1.51 if (!_loadAllInstances(nameSpace, classNames[i], namedInstances))
1015 {
1016 String errMessage = "Failed to load instances in class ";
1017 errMessage.append(classNames[i]);
1018 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1019 }
|
1020 mike 1.48 }
1021
|
1022 mike 1.51 return namedInstances;
|
1023 mike 1.48 }
1024
1025 Array<CIMReference> CIMRepository::enumerateInstanceNames(
1026 const String& nameSpace,
1027 const String& className)
1028 {
|
1029 mike 1.51
1030
1031
|
1032 mike 1.48 // -- Get all descendent classes of this class:
1033
1034 Array<String> classNames;
1035 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
1036 classNames.prepend(className);
1037
|
1038 mike 1.51 // -- Get instance names from each qualifying instance file for the class:
|
1039 mike 1.48
1040 Array<CIMReference> instanceNames;
1041 Array<Uint32> indices;
|
1042 mike 1.51 Array<Uint32> sizes;
|
1043 mike 1.48
1044 for (Uint32 i = 0; i < classNames.size(); i++)
1045 {
|
1046 mike 1.51 // -- Form the name of the class index file:
|
1047 mike 1.48
|
1048 mike 1.51 String path = _getIndexFilePath(nameSpace, classNames[i]);
|
1049 mike 1.48
|
1050 mike 1.51 // Get all instances for that class:
|
1051 mike 1.48
|
1052 mike 1.51 if (!InstanceIndexFile::appendInstanceNamesTo(path, instanceNames,
1053 indices, sizes))
1054 {
1055 String errMessage = "Failed to load instance names in class ";
1056 errMessage.append(classNames[i]);
1057 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1058 }
1059 PEGASUS_ASSERT(instanceNames.size() == indices.size());
1060 PEGASUS_ASSERT(instanceNames.size() == sizes.size());
|
1061 mike 1.48 }
1062
1063 return instanceNames;
1064 }
1065
1066 Array<CIMInstance> CIMRepository::execQuery(
1067 const String& queryLanguage,
1068 const String& query)
1069 {
1070 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, "execQuery()");
1071
|
1072 mike 1.51
|
1073 mike 1.48 return Array<CIMInstance>();
1074 }
1075
1076 Array<CIMObjectWithPath> CIMRepository::associators(
1077 const String& nameSpace,
1078 const CIMReference& objectName,
1079 const String& assocClass,
1080 const String& resultClass,
1081 const String& role,
1082 const String& resultRole,
1083 Boolean includeQualifiers,
1084 Boolean includeClassOrigin,
|
1085 mike 1.51 const CIMPropertyList& propertyList)
|
1086 mike 1.48 {
|
1087 mike 1.51
1088
1089
|
1090 mike 1.48 Array<CIMReference> names = associatorNames(
|
1091 mike 1.51 nameSpace,
1092 objectName,
1093 assocClass,
1094 resultClass,
1095 role,
1096 resultRole);
|
1097 mike 1.48
1098 Array<CIMObjectWithPath> result;
1099
1100 for (Uint32 i = 0, n = names.size(); i < n; i++)
1101 {
|
1102 mike 1.51 String tmpNameSpace = names[i].getNameSpace();
|
1103 mike 1.48
|
1104 mike 1.51 if (tmpNameSpace.size() == 0)
1105 tmpNameSpace = nameSpace;
|
1106 mike 1.48
|
1107 mike 1.51 if (names[i].isClassName())
1108 {
1109 CIMReference tmpRef = names[i];
1110 tmpRef.setHost(String());
1111 tmpRef.setNameSpace(String());
1112
1113 CIMClass cimClass = getClass(
1114 tmpNameSpace,
1115 tmpRef.getClassName(),
1116 false,
1117 includeQualifiers,
1118 includeClassOrigin,
1119 propertyList);
1120
1121 CIMObject cimObject(cimClass);
1122 result.append(CIMObjectWithPath(names[i], cimObject));
1123 }
1124 else
1125 {
1126 CIMReference tmpRef = names[i];
1127 tmpRef.setHost(String());
1128 mike 1.51 tmpRef.setNameSpace(String());
1129
1130 CIMInstance cimInstance = getInstance(
1131 tmpNameSpace,
1132 tmpRef,
1133 false,
1134 includeQualifiers,
1135 includeClassOrigin,
1136 propertyList);
1137
1138 CIMObject cimObject(cimInstance);
1139 result.append(CIMObjectWithPath(names[i], cimObject));
1140 }
|
1141 mike 1.48 }
1142
1143 return result;
1144 }
1145
1146 Array<CIMReference> CIMRepository::associatorNames(
1147 const String& nameSpace,
1148 const CIMReference& objectName,
1149 const String& assocClass,
1150 const String& resultClass,
1151 const String& role,
1152 const String& resultRole)
1153 {
|
1154 mike 1.51
1155
1156
|
1157 mike 1.48 Array<String> associatorNames;
1158
1159 if (objectName.isClassName())
1160 {
|
1161 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
1162 mike 1.48
|
1163 mike 1.51 AssocClassTable::getAssociatorNames(
1164 assocFileName,
1165 objectName.toString(),
1166 assocClass,
1167 resultClass,
1168 role,
1169 resultRole,
1170 associatorNames);
|
1171 mike 1.48 }
1172 else
1173 {
|
1174 mike 1.51 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
|
1175 mike 1.48
|
1176 mike 1.51 AssocInstTable::getAssociatorNames(
1177 assocFileName,
1178 objectName,
1179 assocClass,
1180 resultClass,
1181 role,
1182 resultRole,
1183 associatorNames);
|
1184 mike 1.48 }
1185
1186 Array<CIMReference> result;
1187
1188 for (Uint32 i = 0, n = associatorNames.size(); i < n; i++)
1189 {
|
1190 mike 1.51 CIMReference r = associatorNames[i];
|
1191 mike 1.48
1192 if (r.getHost().size() == 0)
1193 r.setHost(System::getHostName());
1194
1195 if (r.getNameSpace().size() == 0)
1196 r.setNameSpace(nameSpace);
1197
|
1198 mike 1.51 result.append(r);
|
1199 mike 1.48 }
1200
1201 return result;
1202 }
1203
1204 Array<CIMObjectWithPath> CIMRepository::references(
1205 const String& nameSpace,
1206 const CIMReference& objectName,
1207 const String& resultClass,
1208 const String& role,
1209 Boolean includeQualifiers,
1210 Boolean includeClassOrigin,
|
1211 mike 1.51 const CIMPropertyList& propertyList)
|
1212 mike 1.48 {
|
1213 mike 1.51
1214
1215
|
1216 mike 1.48 Array<CIMReference> names = referenceNames(
|
1217 mike 1.51 nameSpace,
1218 objectName,
1219 resultClass,
1220 role);
|
1221 mike 1.48
1222 Array<CIMObjectWithPath> result;
1223
1224 for (Uint32 i = 0, n = names.size(); i < n; i++)
1225 {
|
1226 mike 1.51 String tmpNameSpace = names[i].getNameSpace();
|
1227 mike 1.48
|
1228 mike 1.51 if (tmpNameSpace.size() == 0)
1229 tmpNameSpace = nameSpace;
|
1230 mike 1.48
|
1231 mike 1.51 // ATTN: getInstance() should this be able to handle instance names
1232 // with host names and namespaces?
|
1233 mike 1.48
|
1234 mike 1.51 CIMReference tmpRef = names[i];
1235 tmpRef.setHost(String());
1236 tmpRef.setNameSpace(String());
1237
1238 if (objectName.isClassName())
1239 {
1240 CIMClass cimClass = getClass(
1241 tmpNameSpace,
1242 tmpRef.getClassName(),
1243 false,
1244 includeQualifiers,
1245 includeClassOrigin,
1246 propertyList);
1247
1248 result.append(CIMObjectWithPath(names[i], cimClass));
1249 }
1250 else
1251 {
1252 CIMInstance instance = getInstance(
1253 tmpNameSpace,
1254 tmpRef,
1255 mike 1.51 false,
1256 includeQualifiers,
1257 includeClassOrigin,
1258 propertyList);
|
1259 mike 1.48
|
1260 mike 1.51 result.append(CIMObjectWithPath(names[i], instance));
1261 }
|
1262 mike 1.48 }
1263
1264 return result;
1265 }
1266
1267 Array<CIMReference> CIMRepository::referenceNames(
1268 const String& nameSpace,
1269 const CIMReference& objectName,
1270 const String& resultClass,
1271 const String& role)
1272 {
|
1273 mike 1.51
1274
1275
|
1276 mike 1.48 Array<String> tmpReferenceNames;
1277
1278 if (objectName.isClassName())
1279 {
|
1280 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
1281 mike 1.48
|
1282 mike 1.51 if (!AssocClassTable::getReferenceNames(
1283 assocFileName,
1284 objectName.getClassName(),
1285 resultClass,
1286 role,
1287 tmpReferenceNames))
1288 {
1289 // Ignore error! It's okay not to have references.
1290 }
|
1291 mike 1.48 }
1292 else
1293 {
|
1294 mike 1.51 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
|
1295 mike 1.48
|
1296 mike 1.51 if (!AssocInstTable::getReferenceNames(
1297 assocFileName,
1298 objectName,
1299 resultClass,
1300 role,
1301 tmpReferenceNames))
1302 {
1303 // Ignore error! It's okay not to have references.
1304 }
|
1305 mike 1.48 }
1306
1307 Array<CIMReference> result;
1308
1309 for (Uint32 i = 0, n = tmpReferenceNames.size(); i < n; i++)
1310 {
|
1311 mike 1.51 CIMReference r = tmpReferenceNames[i];
|
1312 mike 1.48
1313 if (r.getHost().size() == 0)
1314 r.setHost(System::getHostName());
1315
1316 if (r.getNameSpace().size() == 0)
1317 r.setNameSpace(nameSpace);
1318
|
1319 mike 1.51 result.append(r);
|
1320 mike 1.48 }
1321
1322 return result;
1323 }
1324
1325 CIMValue CIMRepository::getProperty(
1326 const String& nameSpace,
1327 const CIMReference& instanceName,
1328 const String& propertyName)
1329 {
|
1330 mike 1.51
1331
1332
1333
|
1334 mike 1.48 // -- Get the index for this instance:
1335
1336 String className;
1337 Uint32 index;
|
1338 mike 1.51 Uint32 size;
|
1339 mike 1.48
|
1340 mike 1.51 if (!_getInstanceIndex(nameSpace, instanceName, className, size, index))
1341 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
1342 mike 1.48
1343 // -- Load the instance into memory:
1344
|
1345 mike 1.51 String path = _getInstanceFilePath(nameSpace, className);
|
1346 mike 1.48 CIMInstance cimInstance;
|
1347 mike 1.51 if (!_loadInstance(path, cimInstance, index, size))
1348 {
1349 throw CannotOpenFile(path);
1350 }
|
1351 mike 1.48
1352 // -- Grab the property from the instance:
1353
1354 Uint32 pos = cimInstance.findProperty(propertyName);
1355
|
1356 mike 1.51 // ATTN: This breaks if the property is simply null
|
1357 mike 1.48 if (pos == PEGASUS_NOT_FOUND)
|
1358 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NO_SUCH_PROPERTY, "getProperty()");
|
1359 mike 1.48
1360 CIMProperty prop = cimInstance.getProperty(pos);
1361
1362 // -- Return the value:
1363
1364 return prop.getValue();
1365 }
1366
1367 void CIMRepository::setProperty(
1368 const String& nameSpace,
1369 const CIMReference& instanceName,
1370 const String& propertyName,
1371 const CIMValue& newValue)
1372 {
1373
1374
1375
|
1376 mike 1.51 //
1377 // Create the instance to pass to modifyInstance()
1378 //
1379 CIMInstance instance(instanceName.getClassName());
1380 // ATTN: Is this the correct construction for this property?
1381 instance.addProperty(CIMProperty(propertyName, newValue));
1382 CIMNamedInstance namedInstance(instanceName, instance);
1383
1384 //
1385 // Create the propertyList to pass to modifyInstance()
1386 //
1387 Array<String> propertyListArray;
1388 propertyListArray.append(propertyName);
1389 CIMPropertyList propertyList(propertyListArray);
1390
1391 //
1392 // Modify the instance to set the value of the given property
1393 //
1394 modifyInstance(nameSpace, namedInstance, false, propertyList);
|
1395 mike 1.48 }
1396
1397 CIMQualifierDecl CIMRepository::getQualifier(
1398 const String& nameSpace,
1399 const String& qualifierName)
1400 {
|
1401 mike 1.51
1402
1403
|
1404 mike 1.48 // -- Get path of qualifier file:
1405
1406 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
1407 mike 1.51 nameSpace, qualifierName);
|
1408 mike 1.48
1409 // -- Load qualifier:
1410
1411 CIMQualifierDecl qualifierDecl;
1412
1413 try
1414 {
|
1415 mike 1.51 _LoadObject(qualifierFilePath, qualifierDecl);
|
1416 mike 1.48 }
1417 catch (CannotOpenFile&)
1418 {
|
1419 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, qualifierName);
|
1420 mike 1.48 }
1421
1422 return qualifierDecl;
1423 }
1424
1425 void CIMRepository::setQualifier(
1426 const String& nameSpace,
1427 const CIMQualifierDecl& qualifierDecl)
1428 {
|
1429 mike 1.51
1430
1431
|
1432 mike 1.48 // -- Get path of qualifier file:
1433
1434 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
1435 mike 1.51 nameSpace, qualifierDecl.getName());
|
1436 mike 1.48
1437 // -- If qualifier alread exists, throw exception:
1438
1439 if (FileSystem::existsNoCase(qualifierFilePath))
|
1440 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS, qualifierDecl.getName());
|
1441 mike 1.48
1442 // -- Save qualifier:
1443
1444 _SaveObject(qualifierFilePath, qualifierDecl);
1445 }
1446
1447 void CIMRepository::deleteQualifier(
1448 const String& nameSpace,
1449 const String& qualifierName)
1450 {
|
1451 mike 1.51
1452
1453
|
1454 mike 1.48 // -- Get path of qualifier file:
1455
1456 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
1457 mike 1.51 nameSpace, qualifierName);
|
1458 mike 1.48
1459 // -- Delete qualifier:
1460
1461 if (!FileSystem::removeFileNoCase(qualifierFilePath))
|
1462 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, qualifierName);
|
1463 mike 1.48 }
1464
1465 Array<CIMQualifierDecl> CIMRepository::enumerateQualifiers(
1466 const String& nameSpace)
1467 {
|
1468 mike 1.51
1469
1470
|
1471 mike 1.48 String qualifiersRoot = _nameSpaceManager.getQualifiersRoot(nameSpace);
1472
1473 Array<String> qualifierNames;
1474
1475 if (!FileSystem::getDirectoryContents(qualifiersRoot, qualifierNames))
1476 {
|
1477 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
1478 "enumerateQualifiers(): internal error");
|
1479 mike 1.48 }
1480
1481 Array<CIMQualifierDecl> qualifiers;
1482
1483 for (Uint32 i = 0; i < qualifierNames.size(); i++)
1484 {
|
1485 mike 1.51 CIMQualifierDecl qualifier = getQualifier(nameSpace, qualifierNames[i]);
1486 qualifiers.append(qualifier);
|
1487 mike 1.48 }
1488
1489 return qualifiers;
1490 }
1491
1492 CIMValue CIMRepository::invokeMethod(
1493 const String& nameSpace,
1494 const CIMReference& instanceName,
1495 const String& methodName,
1496 const Array<CIMValue>& inParameters,
1497 Array<CIMValue>& outParameters)
1498 {
1499 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, "invokeMethod()");
|
1500 mike 1.51
1501
1502
|
1503 mike 1.48 return CIMValue();
1504 }
1505
1506 void CIMRepository::createNameSpace(const String& nameSpace)
1507 {
|
1508 mike 1.51
1509
|
1510 mike 1.48 _nameSpaceManager.createNameSpace(nameSpace);
1511 }
1512
1513 Array<String> CIMRepository::enumerateNameSpaces() const
1514 {
|
1515 mike 1.51
1516
|
1517 mike 1.48 Array<String> nameSpaceNames;
1518 _nameSpaceManager.getNameSpaceNames(nameSpaceNames);
1519 return nameSpaceNames;
1520 }
1521
1522 void CIMRepository::deleteNameSpace(const String& nameSpace)
1523 {
|
1524 mike 1.51
1525
1526
|
1527 mike 1.48 _nameSpaceManager.deleteNameSpace(nameSpace);
1528 }
1529
|
1530 mike 1.51 //----------------------------------------------------------------------
1531 //
1532 // _getIndexFilePath()
1533 //
1534 // returns the file path of the instance index file.
1535 //
1536 //----------------------------------------------------------------------
1537
|
1538 mike 1.48 String CIMRepository::_getIndexFilePath(
1539 const String& nameSpace,
1540 const String& className) const
1541 {
1542 String tmp = _nameSpaceManager.getInstanceFileBase(nameSpace, className);
1543 tmp.append(".idx");
1544 return tmp;
1545 }
1546
|
1547 mike 1.51 //----------------------------------------------------------------------
1548 //
1549 // _getInstanceFilePath()
1550 //
1551 // returns the file path of the instance file.
1552 //
1553 //----------------------------------------------------------------------
1554
|
1555 mike 1.48 String CIMRepository::_getInstanceFilePath(
1556 const String& nameSpace,
|
1557 mike 1.51 const String& className) const
|
1558 mike 1.48 {
1559 String tmp = _nameSpaceManager.getInstanceFileBase(nameSpace, className);
|
1560 mike 1.51 tmp.append(".instances");
|
1561 mike 1.48 return tmp;
|
1562 mike 1.51 }
1563
1564 //----------------------------------------------------------------------
1565 //
1566 // _loadInstance()
1567 //
1568 // Loads an instance object from disk to memory. Returns true on
1569 // success.
1570 //
1571 //----------------------------------------------------------------------
1572
1573 Boolean CIMRepository::_loadInstance(
1574 const String& path,
1575 CIMInstance& object,
1576 Uint32 index,
1577 Uint32 size)
1578 {
1579 // Load instance from instance file into memory:
1580
1581
1582 Array<Sint8> data;
1583 mike 1.51 if (!InstanceFile::loadInstance(path, index, size, data))
1584 {
1585 return false;
1586 }
1587
1588 XmlParser parser((char*)data.getData());
1589
1590 XmlReader::getObject(parser, object);
1591
1592 return true;
1593 }
1594
1595 //----------------------------------------------------------------------
1596 //
1597 // _loadAllInstances()
1598 //
1599 // Loads all the instance objects for a given class from disk to memory.
1600 // Returns true on success.
1601 //
1602 //----------------------------------------------------------------------
1603
1604 mike 1.51 Boolean CIMRepository::_loadAllInstances(
1605 const String& nameSpace,
1606 const String& className,
1607 Array<CIMNamedInstance>& namedInstances)
1608 {
1609 Array<CIMReference> instanceNames;
1610 Array<Sint8> data;
1611 Array<Uint32> indices;
1612 Array<Uint32> sizes;
1613
1614 //
1615 // Form the name of the instance index file
1616 //
1617 String indexFilePath = _getIndexFilePath(nameSpace, className);
1618
1619 //
1620 // Form the name of the instance file
1621 //
1622 String instanceFilePath = _getInstanceFilePath(nameSpace, className);
1623
1624 //
1625 mike 1.51 // Get all instance names and record information from the index file
1626 //
1627 if (!InstanceIndexFile::appendInstanceNamesTo(
1628 indexFilePath, instanceNames, indices, sizes))
1629 {
1630 return false;
1631 }
1632 PEGASUS_ASSERT(instanceNames.size() == indices.size());
1633 PEGASUS_ASSERT(instanceNames.size() == sizes.size());
1634
1635 //
1636 // Load all instance data from the instance file
1637 //
1638 if (instanceNames.size() > 0)
1639 {
1640 if (!InstanceFile::loadAllInstances(instanceFilePath, data))
1641 {
1642 return false;
1643 }
1644
1645 //
1646 mike 1.51 // for each instance loaded, call XML parser to parse the XML
1647 // data and create a CIMInstance object.
1648 //
1649 CIMInstance tmpInstance;
1650
1651 Uint32 bufferSize = data.size();
1652 char* buffer = (char*)data.getData();
1653
1654 for (Uint32 i = 0; i < instanceNames.size(); i++)
1655 {
1656 XmlParser parser(&(buffer[indices[i]]));
1657
1658 XmlReader::getObject(parser, tmpInstance);
1659
1660 namedInstances.append(CIMNamedInstance(instanceNames[i], tmpInstance));
1661 }
1662 }
1663
1664 return true;
1665 }
1666
1667 mike 1.51 //----------------------------------------------------------------------
1668 //
1669 // _saveInstance()
1670 //
1671 // Saves an instance object from memory to disk file. Returns true
1672 // on success.
1673 //
1674 //----------------------------------------------------------------------
1675
1676 Boolean CIMRepository::_saveInstance(
1677 const String& path,
1678 const CIMInstance& object,
1679 Uint32& index,
1680 Uint32& size)
1681 {
1682 Array<Sint8> out;
1683 object.toXml(out);
1684
1685 if (!InstanceFile::insertInstance(out, path, index, size))
1686 {
1687 return false;
1688 mike 1.51 }
1689
1690 return true;
1691 }
1692
1693 //----------------------------------------------------------------------
1694 //
1695 // _modifyInstance()
1696 //
1697 // Modifies an instance object saved in the disk file. Returns true
1698 // on success.
1699 //
1700 //----------------------------------------------------------------------
1701
1702 Boolean CIMRepository::_modifyInstance(
1703 const String& path,
1704 const CIMInstance& object,
1705 Uint32 oldIndex,
1706 Uint32 oldSize,
1707 Uint32& newIndex,
1708 Uint32& newSize)
1709 mike 1.51 {
1710 Array<Sint8> out;
1711 object.toXml(out);
1712
1713 if (!InstanceFile::modifyInstance(out, path, oldIndex, oldSize, newIndex,
1714 newSize))
1715 {
1716 return false;
1717 }
1718
1719 return true;
1720 }
1721
1722 //------------------------------------------------------------------------------
1723 //
1724 // _renameTempInstanceAndIndexFiles()
1725 //
1726 // Renames the temporary instance and instance index files back to the
1727 // original files. The temporary files were created for an insert,
1728 // remove, or modify operation (to avoid data inconsistency between
1729 // the two files in case of unexpected system termination or failure).
1730 mike 1.51 // This method is called after a successful insert, remove, or modify
1731 // operation on BOTH the index file and the instance file. Returns
1732 // true on success.
1733 //
1734 //------------------------------------------------------------------------------
1735
1736 Boolean CIMRepository::_renameTempInstanceAndIndexFiles(
1737 const String& indexFilePath,
1738 const String& instanceFilePath)
1739 {
1740 //
1741 // Rename the original files to backup files
1742 //
1743 // This is done so that we would not lose the original files if an error
1744 // occurs in renaming the temporary files back after the original files
1745 // have been removed.
1746 //
1747 String realIndexFilePath;
1748 if (FileSystem::existsNoCase(indexFilePath, realIndexFilePath))
1749 {
1750 if (!FileSystem::renameFile(realIndexFilePath,
1751 mike 1.51 realIndexFilePath + ".orig"))
1752 return false;
1753 }
1754 else
1755 {
1756 realIndexFilePath = indexFilePath;
1757 }
1758
1759 String realInstanceFilePath;
1760 if (FileSystem::existsNoCase(instanceFilePath, realInstanceFilePath))
1761 {
1762 if (!FileSystem::renameFile(realInstanceFilePath,
1763 realInstanceFilePath + ".orig"))
1764 return false;
1765 }
1766 else
1767 {
1768 realInstanceFilePath = instanceFilePath;
1769 }
1770
1771 //
1772 mike 1.51 // Rename the temporary instance and index files back to be the original
1773 // files.
1774 //
1775 // If the index file is now empty (zero size), delete the temporary
1776 // files instead.
1777 //
1778 Uint32 fileSize;
1779 String tmpIndexFilePath = realIndexFilePath + ".tmp";
1780 String tmpInstanceFilePath = realInstanceFilePath + ".tmp";
1781
1782 if (!FileSystem::getFileSizeNoCase(tmpIndexFilePath, fileSize))
1783 return false;
1784
1785 if (fileSize == 0)
1786 {
1787 if (!FileSystem::removeFileNoCase(tmpIndexFilePath))
1788 return false;
1789
1790 if (!FileSystem::removeFileNoCase(tmpInstanceFilePath))
1791 return false;
1792 }
1793 mike 1.51 else
1794 {
1795 if (!FileSystem::renameFile(tmpIndexFilePath, realIndexFilePath))
1796 return false;
1797
1798 if (!FileSystem::renameFile(tmpInstanceFilePath, realInstanceFilePath))
1799 return false;
1800 }
1801
1802 //
1803 // Now remove the backup files
1804 //
1805 FileSystem::removeFile(realIndexFilePath + ".orig");
1806 FileSystem::removeFile(realInstanceFilePath + ".orig");
1807
1808 return true;
|
1809 mike 1.48 }
1810
|
1811 bob 1.49 void CIMRepository::setDeclContext(RepositoryDeclContext *context)
1812 {
1813 _context = context;
1814 }
1815
|
1816 mike 1.48 PEGASUS_NAMESPACE_END
|