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 kumpf 1.70 // Carol Ann Krug Graves, Hewlett-Packard Company
29 // (carolann_graves@hp.com)
|
30 mike 1.48 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
|
33 mike 1.51 #include <Pegasus/Common/Config.h>
|
34 mike 1.48 #include <cctype>
35 #include <cstdio>
36 #include <fstream>
37 #include <Pegasus/Common/Pair.h>
38 #include <Pegasus/Common/Destroyer.h>
39 #include <Pegasus/Common/FileSystem.h>
40 #include <Pegasus/Common/Exception.h>
41 #include <Pegasus/Common/XmlReader.h>
42 #include <Pegasus/Common/XmlWriter.h>
43 #include <Pegasus/Common/DeclContext.h>
44 #include <Pegasus/Common/DeclContext.h>
45 #include <Pegasus/Common/System.h>
|
46 kumpf 1.52 #include <Pegasus/Common/Tracer.h>
|
47 kumpf 1.63 #include <Pegasus/Common/PegasusVersion.h>
48
|
49 mike 1.48 #include "CIMRepository.h"
50 #include "RepositoryDeclContext.h"
51 #include "InstanceIndexFile.h"
|
52 mike 1.53 #include "InstanceDataFile.h"
|
53 mike 1.48 #include "AssocInstTable.h"
54 #include "AssocClassTable.h"
55
56 #define INDENT_XML_FILES
57
58 PEGASUS_USING_STD;
59
60 PEGASUS_NAMESPACE_BEGIN
61
|
62 mike 1.53 static const Uint32 _MAX_FREE_COUNT = 16;
63
|
64 mike 1.48 ////////////////////////////////////////////////////////////////////////////////
65 //
66 // _LoadObject()
67 //
|
68 mike 1.51 // Loads objects (classes and qualifiers) from disk to
69 // memory objects.
|
70 mike 1.48 //
71 ////////////////////////////////////////////////////////////////////////////////
72
73 template<class Object>
74 void _LoadObject(
75 const String& path,
76 Object& object)
77 {
|
78 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_LoadObject");
79
|
80 mike 1.48 // Get the real path of the file:
81
82 String realPath;
83
84 if (!FileSystem::existsNoCase(path, realPath))
|
85 kumpf 1.61 {
86 String traceString = path + " does not exists.";
87 PEG_TRACE_STRING(TRC_REPOSITORY, Tracer::LEVEL4, traceString);
|
88 kumpf 1.58 PEG_METHOD_EXIT();
|
89 mike 1.51 throw CannotOpenFile(path);
|
90 kumpf 1.58 }
|
91 mike 1.48
|
92 kumpf 1.61 PEG_TRACE_STRING(TRC_REPOSITORY, Tracer::LEVEL4, "realpath = " + realPath);
93
|
94 mike 1.48 // Load file into memory:
95
96 Array<Sint8> data;
97 FileSystem::loadFileToMemory(data, realPath);
98 data.append('\0');
99
100 XmlParser parser((char*)data.getData());
101
102 XmlReader::getObject(parser, object);
|
103 kumpf 1.58
104 PEG_METHOD_EXIT();
|
105 mike 1.48 }
106
107 ////////////////////////////////////////////////////////////////////////////////
108 //
109 // _SaveObject()
110 //
|
111 mike 1.51 // Saves objects (classes and qualifiers) from memory to
112 // disk files.
|
113 mike 1.48 //
114 ////////////////////////////////////////////////////////////////////////////////
115
|
116 kumpf 1.66 void _SaveObject(const String& path, Array<Sint8>& objectXml)
|
117 mike 1.48 {
|
118 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_SaveObject");
119
|
120 mike 1.48 ArrayDestroyer<char> destroyer(path.allocateCString());
121 PEGASUS_STD(ofstream) os(destroyer.getPointer() PEGASUS_IOS_BINARY);
122
123 if (!os)
|
124 kumpf 1.58 {
125 PEG_METHOD_EXIT();
|
126 mike 1.51 throw CannotOpenFile(path);
|
127 kumpf 1.58 }
|
128 mike 1.48
129 #ifdef INDENT_XML_FILES
|
130 kumpf 1.66 objectXml.append('\0');
131 XmlWriter::indentedPrint(os, objectXml.getData(), 2);
|
132 mike 1.48 #else
|
133 kumpf 1.66 os.write((char*)objectXml.getData(), objectXml.size());
|
134 mike 1.48 #endif
|
135 kumpf 1.58
136 PEG_METHOD_EXIT();
|
137 mike 1.48 }
138
139 static String _MakeAssocInstPath(
140 const String& nameSpace,
141 const String& repositoryRoot)
142 {
|
143 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_MakeAssocInstPath");
144
|
145 mike 1.48 String tmp = nameSpace;
146 tmp.translate('/', '#');
|
147 kumpf 1.58
|
148 kumpf 1.64 String returnString(repositoryRoot);
149 returnString.append('/');
150 returnString.append(tmp);
151 returnString.append("/instances/associations");
152
|
153 kumpf 1.58 PEG_METHOD_EXIT();
|
154 kumpf 1.64 return returnString;
|
155 mike 1.48 }
156
157 static String _MakeAssocClassPath(
158 const String& nameSpace,
159 const String& repositoryRoot)
160 {
|
161 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_MakeAssocClassPath");
162
|
163 mike 1.48 String tmp = nameSpace;
164 tmp.translate('/', '#');
|
165 kumpf 1.58
|
166 kumpf 1.64 String returnString(repositoryRoot);
167 returnString.append('/');
168 returnString.append(tmp);
169 returnString.append("/classes/associations");
170
|
171 kumpf 1.58 PEG_METHOD_EXIT();
|
172 kumpf 1.64 return returnString;
|
173 mike 1.48 }
174
175 ////////////////////////////////////////////////////////////////////////////////
176 //
177 // CIMRepository
178 //
179 // The following are not implemented:
180 //
181 // CIMRepository::execQuery()
182 // CIMRepository::referencesNames()
183 // CIMRepository::invokeMethod()
184 //
185 // Note that invokeMethod() will not never implemented since it is not
186 // meaningful for a repository.
187 //
188 // ATTN: make operations on files non-case-sensitive.
189 //
190 ////////////////////////////////////////////////////////////////////////////////
191
192 CIMRepository::CIMRepository(const String& repositoryRoot)
|
193 mike 1.51 : _repositoryRoot(repositoryRoot), _nameSpaceManager(repositoryRoot),
|
194 kumpf 1.56 _lock(), _resolveInstance(true)
|
195 mike 1.48 {
|
196 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::CIMRepository");
197
|
198 mike 1.48 _context = new RepositoryDeclContext(this);
|
199 mike 1.51 _isDefaultInstanceProvider = (ConfigManager::getInstance()->getCurrentValue(
200 "repositoryIsDefaultInstanceProvider") == "true");
|
201 kumpf 1.58
202 PEG_METHOD_EXIT();
|
203 mike 1.48 }
204
205 CIMRepository::~CIMRepository()
206 {
|
207 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::~CIMRepository");
208
|
209 mike 1.48 delete _context;
|
210 kumpf 1.58
211 PEG_METHOD_EXIT();
|
212 mike 1.48 }
213
|
214 mike 1.51
215 void CIMRepository::read_lock(void) throw(IPCException)
216 {
|
217 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::read_lock");
218
|
219 mike 1.51 _lock.wait_read(pegasus_thread_self());
|
220 kumpf 1.58
221 PEG_METHOD_EXIT();
|
222 mike 1.51 }
223
224 void CIMRepository::read_unlock(void)
225 {
|
226 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::read_unlock");
227
|
228 mike 1.51 _lock.unlock_read(pegasus_thread_self());
|
229 kumpf 1.58
230 PEG_METHOD_EXIT();
|
231 mike 1.51 }
232
233 void CIMRepository::write_lock(void) throw(IPCException)
234 {
|
235 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::write_lock");
236
|
237 mike 1.51 _lock.wait_write(pegasus_thread_self());
|
238 kumpf 1.58
239 PEG_METHOD_EXIT();
|
240 mike 1.51 }
241
242 void CIMRepository::write_unlock(void)
243 {
|
244 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::write_unlock");
245
|
246 mike 1.51 _lock.unlock_write(pegasus_thread_self());
|
247 kumpf 1.58
248 PEG_METHOD_EXIT();
|
249 mike 1.51 }
250
|
251 mike 1.48 CIMClass CIMRepository::getClass(
252 const String& nameSpace,
253 const String& className,
254 Boolean localOnly,
255 Boolean includeQualifiers,
256 Boolean includeClassOrigin,
|
257 mike 1.51 const CIMPropertyList& propertyList)
|
258 mike 1.48 {
|
259 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::getClass");
260
|
261 kumpf 1.61 PEG_TRACE_STRING(TRC_REPOSITORY, Tracer::LEVEL4, "nameSpace = " +
262 nameSpace + ", className = " + className);
263
|
264 mike 1.48 // ATTN: localOnly, includeQualifiers, and includeClassOrigin are ignored
265 // for now.
266
267 String classFilePath;
268 classFilePath = _nameSpaceManager.getClassFilePath(nameSpace, className);
269
270 CIMClass cimClass;
|
271 mike 1.51
272 try
273 {
274 _LoadObject(classFilePath, cimClass);
275 }
|
276 mike 1.53 catch (Exception&)
|
277 mike 1.51 {
|
278 kumpf 1.58 PEG_METHOD_EXIT();
|
279 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, className);
280 }
|
281 mike 1.48
|
282 kumpf 1.58 PEG_METHOD_EXIT();
|
283 mike 1.48 return cimClass;
284 }
285
286 Boolean CIMRepository::_getInstanceIndex(
287 const String& nameSpace,
|
288 kumpf 1.68 const CIMObjectPath& instanceName,
|
289 mike 1.48 String& className,
|
290 mike 1.53 Uint32& index,
|
291 mike 1.51 Uint32& size,
|
292 mike 1.48 Boolean searchSuperClasses) const
293 {
|
294 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_getInstanceIndex");
295
|
296 mike 1.53 //
297 // Get all descendent classes of this class:
298 //
|
299 mike 1.51
|
300 mike 1.48 className = instanceName.getClassName();
301
302 Array<String> classNames;
303 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
304 classNames.prepend(className);
305
|
306 mike 1.53 //
307 // Get all superclasses of this one:
308 //
|
309 mike 1.48
310 if (searchSuperClasses)
|
311 mike 1.51 _nameSpaceManager.getSuperClassNames(nameSpace, className, classNames);
|
312 mike 1.48
|
313 mike 1.53 //
314 // Get instance names from each qualifying instance file for the class:
315 //
|
316 mike 1.48
317 for (Uint32 i = 0; i < classNames.size(); i++)
318 {
|
319 kumpf 1.68 CIMObjectPath tmpInstanceName = instanceName;
|
320 mike 1.51 tmpInstanceName.setClassName(classNames[i]);
|
321 mike 1.48
|
322 mike 1.53 //
323 // Lookup index of instance:
324 //
|
325 mike 1.48
|
326 mike 1.53 String path = _getInstanceIndexFilePath(nameSpace, classNames[i]);
|
327 mike 1.48
|
328 mike 1.53 if (InstanceIndexFile::lookupEntry(path, tmpInstanceName, index, size))
|
329 mike 1.51 {
330 className = classNames[i];
|
331 kumpf 1.58 PEG_METHOD_EXIT();
|
332 mike 1.51 return true;
333 }
|
334 mike 1.48 }
335
|
336 kumpf 1.58 PEG_METHOD_EXIT();
|
337 mike 1.48 return false;
338 }
339
340 CIMInstance CIMRepository::getInstance(
341 const String& nameSpace,
|
342 kumpf 1.68 const CIMObjectPath& instanceName,
|
343 mike 1.48 Boolean localOnly,
344 Boolean includeQualifiers,
345 Boolean includeClassOrigin,
|
346 mike 1.55 const CIMPropertyList& propertyList)
|
347 mike 1.48 {
|
348 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::getInstance");
349
|
350 mike 1.53 //
351 // Get the index for this instance:
352 //
|
353 mike 1.48
354 String className;
355 Uint32 index;
|
356 mike 1.51 Uint32 size;
357
|
358 mike 1.53 if (!_getInstanceIndex(nameSpace, instanceName, className, index, size))
|
359 mike 1.48 {
|
360 kumpf 1.52 PEG_METHOD_EXIT();
|
361 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
362 mike 1.48 }
363
|
364 mike 1.53 //
365 // Load the instance from file:
366 //
|
367 mike 1.48
|
368 mike 1.53 String path = _getInstanceDataFilePath(nameSpace, className);
|
369 mike 1.48 CIMInstance cimInstance;
|
370 mike 1.53
|
371 mike 1.51 if (!_loadInstance(path, cimInstance, index, size))
372 {
|
373 kumpf 1.52 PEG_METHOD_EXIT();
|
374 mike 1.51 throw CannotOpenFile(path);
375 }
376
|
377 mike 1.54 //
378 // Resolve the instance (if requested):
379 //
380
381 if (_resolveInstance)
382 {
383 CIMConstClass cimClass;
384 cimInstance.resolve(_context, nameSpace, cimClass, true);
385 }
386
|
387 kumpf 1.52 PEG_METHOD_EXIT();
|
388 mike 1.48 return cimInstance;
389 }
390
391 void CIMRepository::deleteClass(
392 const String& nameSpace,
393 const String& className)
394 {
|
395 kumpf 1.61 PEG_METHOD_ENTER(TRC_REPOSITORY,"CIMRepository::deleteClass");
|
396 kumpf 1.58
|
397 mike 1.53 //
398 // Get the class and check to see if it is an association class:
399 //
|
400 mike 1.51
|
401 mike 1.48 CIMClass cimClass = getClass(nameSpace, className, false);
402 Boolean isAssociation = cimClass.isAssociation();
403
|
404 mike 1.53 //
405 // Disallow deletion if class has instances:
406 //
|
407 mike 1.48
|
408 mike 1.53 String indexFilePath = _getInstanceIndexFilePath(nameSpace, className);
|
409 kumpf 1.61 PEG_TRACE_STRING(TRC_REPOSITORY, Tracer::LEVEL4,
410 "instance indexFilePath = " + indexFilePath);
|
411 mike 1.53
412 String dataFilePath = _getInstanceDataFilePath(nameSpace, className);
|
413 kumpf 1.61 PEG_TRACE_STRING(TRC_REPOSITORY, Tracer::LEVEL4,
414 "instance dataFilePath = " + dataFilePath);
|
415 mike 1.48
|
416 mike 1.53 if (InstanceIndexFile::hasNonFreeEntries(indexFilePath))
|
417 kumpf 1.58 {
418 PEG_METHOD_EXIT();
|
419 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_CLASS_HAS_INSTANCES, className);
|
420 kumpf 1.58 }
|
421 mike 1.48
|
422 mike 1.53 //
423 // Delete the class. The NameSpaceManager::deleteClass() method throws
424 // and exception if the class has sublclasses.
425 //
|
426 kumpf 1.58 try
427 {
428 _nameSpaceManager.deleteClass(nameSpace, className);
429 }
430 catch (CIMException& e)
431 {
432 PEG_METHOD_EXIT();
433 throw e;
434 }
|
435 mike 1.48
|
436 mike 1.53 FileSystem::removeFileNoCase(indexFilePath);
|
437 kumpf 1.61
|
438 mike 1.53 FileSystem::removeFileNoCase(dataFilePath);
439
440 //
441 // Kill off empty instance files:
442 //
443
444 //
445 // Remove association:
446 //
|
447 mike 1.48
448 if (isAssociation)
449 {
|
450 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
451 mike 1.48
|
452 mike 1.51 if (FileSystem::exists(assocFileName))
453 AssocClassTable::deleteAssociation(assocFileName, className);
|
454 mike 1.48 }
|
455 kumpf 1.61
|
456 kumpf 1.58 PEG_METHOD_EXIT();
|
457 mike 1.48 }
458
|
459 mike 1.53 void _CompactInstanceRepository(
460 const String& indexFilePath,
461 const String& dataFilePath)
462 {
|
463 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_CompactInstanceRepository");
464
|
465 mike 1.53 //
466 // Compact the data file first:
467 //
468
469 Array<Uint32> freeFlags;
470 Array<Uint32> indices;
471 Array<Uint32> sizes;
|
472 kumpf 1.68 Array<CIMObjectPath> instanceNames;
|
473 mike 1.53
474 if (!InstanceIndexFile::enumerateEntries(
475 indexFilePath, freeFlags, indices, sizes, instanceNames, true))
476 {
|
477 kumpf 1.58 PEG_METHOD_EXIT();
|
478 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "compact failed");
479 }
480
481 if (!InstanceDataFile::compact(dataFilePath, freeFlags, indices, sizes))
|
482 kumpf 1.58 {
483 PEG_METHOD_EXIT();
|
484 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "compact failed");
|
485 kumpf 1.58 }
|
486 mike 1.53
487 //
488 // Now compact the index file:
489 //
490
491 if (!InstanceIndexFile::compact(indexFilePath))
|
492 kumpf 1.58 {
493 PEG_METHOD_EXIT();
|
494 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "compact failed");
|
495 kumpf 1.58 }
496
497 PEG_METHOD_EXIT();
|
498 mike 1.53 }
499
|
500 mike 1.48 void CIMRepository::deleteInstance(
501 const String& nameSpace,
|
502 kumpf 1.68 const CIMObjectPath& instanceName)
|
503 mike 1.48 {
|
504 mike 1.53 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::deleteInstance");
|
505 mike 1.51
506 String errMessage;
507
|
508 mike 1.53 //
509 // Get paths of index and data files:
510 //
511
512 String indexFilePath = _getInstanceIndexFilePath(
513 nameSpace, instanceName.getClassName());
|
514 mike 1.48
|
515 mike 1.53 String dataFilePath = _getInstanceDataFilePath(
|
516 mike 1.51 nameSpace, instanceName.getClassName());
|
517 mike 1.48
|
518 mike 1.53 //
519 // Attempt rollback (if there are no rollback files, this will have no
520 // effect). This code is here to rollback uncommitted changes left over
521 // from last time an instance-oriented function was called.
522 //
523
524 if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
525 {
526 PEG_METHOD_EXIT();
527 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
528 }
529
530 if (!InstanceDataFile::rollbackTransaction(dataFilePath))
531 {
532 PEG_METHOD_EXIT();
533 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
534 }
535
536 //
537 // Lookup instance from the index file (raise error if not found).
538 //
539 mike 1.53
|
540 mike 1.48 Uint32 index;
|
541 mike 1.51 Uint32 size;
|
542 mike 1.48
|
543 mike 1.53 if (!InstanceIndexFile::lookupEntry(
544 indexFilePath, instanceName, index, size))
|
545 kumpf 1.52 {
546 PEG_METHOD_EXIT();
|
547 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
548 kumpf 1.52 }
|
549 mike 1.48
|
550 mike 1.53 //
551 // Begin the transaction (any return prior to commit will cause
552 // a rollback next time an instance-oriented routine is invoked).
553 //
554
555 if (!InstanceIndexFile::beginTransaction(indexFilePath))
556 {
557 PEG_METHOD_EXIT();
558 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
559 }
|
560 mike 1.48
|
561 mike 1.53 if (!InstanceDataFile::beginTransaction(dataFilePath))
|
562 mike 1.48 {
|
563 kumpf 1.52 PEG_METHOD_EXIT();
|
564 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
|
565 mike 1.48 }
566
|
567 mike 1.53 //
568 // Remove entry from index file.
569 //
|
570 mike 1.48
|
571 mike 1.53 Uint32 freeCount;
|
572 mike 1.48
|
573 mike 1.53 if (!InstanceIndexFile::deleteEntry(indexFilePath, instanceName, freeCount))
|
574 mike 1.48 {
|
575 mike 1.53 errMessage.append("Failed to delete instance: ");
|
576 mike 1.51 errMessage.append(instanceName.toString());
|
577 kumpf 1.52 PEG_METHOD_EXIT();
|
578 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
579 mike 1.48 }
580
|
581 mike 1.53 //
582 // Commit the transaction:
583 //
|
584 mike 1.51
|
585 mike 1.53 if (!InstanceIndexFile::commitTransaction(indexFilePath))
586 {
587 PEG_METHOD_EXIT();
588 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
589 }
590
591 if (!InstanceDataFile::commitTransaction(dataFilePath))
|
592 mike 1.48 {
|
593 kumpf 1.52 PEG_METHOD_EXIT();
|
594 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
|
595 mike 1.48 }
596
|
597 mike 1.53 //
598 // Compact the index and data files if the free count max was
599 // reached.
600 //
601
602 if (freeCount == _MAX_FREE_COUNT)
603 _CompactInstanceRepository(indexFilePath, dataFilePath);
604
605 //
606 // Delete from assocation table (if an assocation).
607 //
|
608 mike 1.48
609 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
610
611 if (FileSystem::exists(assocFileName))
|
612 mike 1.51 AssocInstTable::deleteAssociation(assocFileName, instanceName);
|
613 kumpf 1.52
614 PEG_METHOD_EXIT();
|
615 mike 1.48 }
616
617 void CIMRepository::_createAssocClassEntries(
618 const String& nameSpace,
619 const CIMConstClass& assocClass)
620 {
|
621 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_createAssocClassEntries");
622
|
623 mike 1.48 // Open input file:
624
|
625 mike 1.51
|
626 mike 1.48 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
627 ofstream os;
628
629 if (!OpenAppend(os, assocFileName))
|
630 kumpf 1.58 {
631 PEG_METHOD_EXIT();
|
632 mike 1.51 throw CannotOpenFile(assocFileName);
|
633 kumpf 1.58 }
|
634 mike 1.48
635 // Get the association's class name:
636
637 String assocClassName = assocClass.getClassName();
638
639 // For each property:
640
641 Uint32 n = assocClass.getPropertyCount();
642
643 for (Uint32 i = 0; i < n; i++)
644 {
|
645 mike 1.51 CIMConstProperty fromProp = assocClass.getProperty(i);
|
646 mike 1.48
|
647 mike 1.51 if (fromProp.getType() == CIMType::REFERENCE)
648 {
649 for (Uint32 j = 0; j < n; j++)
650 {
651 CIMConstProperty toProp = assocClass.getProperty(j);
652
653 if (toProp.getType() == CIMType::REFERENCE &&
654 fromProp.getName() != toProp.getName())
655 {
656 String fromClassName = fromProp.getReferenceClassName();
657 String fromPropertyName = fromProp.getName();
658 String toClassName = toProp.getReferenceClassName();
659 String toPropertyName = toProp.getName();
660
661 AssocClassTable::append(
662 os,
663 assocClassName,
664 fromClassName,
665 fromPropertyName,
666 toClassName,
667 toPropertyName);
668 mike 1.51 }
669 }
670 }
|
671 mike 1.48 }
|
672 kumpf 1.58
673 PEG_METHOD_EXIT();
|
674 mike 1.48 }
675
676 void CIMRepository::createClass(
677 const String& nameSpace,
678 const CIMClass& newClass)
679 {
|
680 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::createClass");
681
|
682 mike 1.48 // -- Resolve the class:
|
683 mike 1.51 CIMClass cimClass(newClass);
684
|
685 mike 1.48 cimClass.resolve(_context, nameSpace);
686
687 // -- If an association, populate associations file:
688
689 if (cimClass.isAssociation())
|
690 mike 1.51 _createAssocClassEntries(nameSpace, cimClass);
|
691 mike 1.48
692 // -- Create namespace manager entry:
693
694 String classFilePath;
695
696 _nameSpaceManager.createClass(nameSpace, cimClass.getClassName(),
|
697 mike 1.51 cimClass.getSuperClassName(), classFilePath);
|
698 mike 1.48
699 // -- Create the class file:
700
|
701 kumpf 1.66 Array<Sint8> classXml;
702 XmlWriter::appendClassElement(classXml, cimClass);
703 _SaveObject(classFilePath, classXml);
|
704 kumpf 1.58
705 PEG_METHOD_EXIT();
|
706 mike 1.48 }
707
708 /*------------------------------------------------------------------------------
709
710 This routine does the following:
711
|
712 mike 1.51 1. Creates two entries in the association file for each relationship
713 formed by this new assocation instance. A binary association
714 (one with two references) ties two instances together. Suppose
715 there are two instances: I1 and I2. Then two entries are created:
716
717 I2 -> I1
718 I1 -> I2
719
720 For a ternary relationship, six entries will be created. Suppose
721 there are three instances: I1, I2, and I3:
722
723 I1 -> I2
724 I1 -> I3
725 I2 -> I1
726 I2 -> I3
727 I3 -> I1
728 I3 -> I2
729
730 So for an N-ary relationship, there will be 2*N entries created.
731
732 2. Verifies that the association instance refers to real objects.
733 mike 1.51 (note that an association reference may refer to either an instance
734 or a class). Throws an exception if one of the references does not
735 refer to a valid object.
|
736 mike 1.48
737 ------------------------------------------------------------------------------*/
738
739 void CIMRepository::_createAssocInstEntries(
740 const String& nameSpace,
741 const CIMConstClass& cimClass,
742 const CIMInstance& cimInstance,
|
743 kumpf 1.68 const CIMObjectPath& instanceName)
|
744 mike 1.48 {
|
745 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_createAssocInstEntries");
746
|
747 mike 1.48 // Open input file:
748
749 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
750 ofstream os;
751
752 if (!OpenAppend(os, assocFileName))
|
753 kumpf 1.58 {
754 PEG_METHOD_EXIT();
|
755 mike 1.51 throw CannotOpenFile(assocFileName);
|
756 kumpf 1.58 }
|
757 mike 1.48
758 // Get the association's instance name and class name:
759
760 String assocInstanceName = instanceName.toString();
761 String assocClassName = instanceName.getClassName();
762
763 // For each property:
764
765 for (Uint32 i = 0, n = cimInstance.getPropertyCount(); i < n; i++)
766 {
|
767 mike 1.51 CIMConstProperty fromProp = cimInstance.getProperty(i);
|
768 mike 1.48
|
769 mike 1.51 // If a reference property:
|
770 mike 1.48
|
771 mike 1.51 if (fromProp.getType() == CIMType::REFERENCE)
772 {
773 // For each property:
774
775 for (Uint32 j = 0, n = cimInstance.getPropertyCount(); j < n; j++)
776 {
777 CIMConstProperty toProp = cimInstance.getProperty(j);
778
779 // If a reference property and not the same property:
780
781 if (toProp.getType() == CIMType::REFERENCE &&
782 fromProp.getName() != toProp.getName())
783 {
|
784 kumpf 1.68 CIMObjectPath fromRef;
|
785 mike 1.51 fromProp.getValue().get(fromRef);
786
|
787 kumpf 1.68 CIMObjectPath toRef;
|
788 mike 1.51 toProp.getValue().get(toRef);
789
790 String fromObjectName = fromRef.toString();
791 String fromClassName = fromRef.getClassName();
792 String fromPropertyName = fromProp.getName();
793 String toObjectName = toRef.toString();
794 String toClassName = toRef.getClassName();
795 String toPropertyName = toProp.getName();
796
797 AssocInstTable::append(
798 os,
799 assocInstanceName,
800 assocClassName,
801 fromObjectName,
802 fromClassName,
803 fromPropertyName,
804 toObjectName,
805 toClassName,
806 toPropertyName);
807 }
808 }
809 mike 1.51 }
|
810 mike 1.48 }
|
811 kumpf 1.58
812 PEG_METHOD_EXIT();
|
813 mike 1.48 }
814
|
815 kumpf 1.68 CIMObjectPath CIMRepository::createInstance(
|
816 mike 1.48 const String& nameSpace,
817 const CIMInstance& newInstance)
818 {
|
819 kumpf 1.61 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::createInstance");
|
820 mike 1.51
821 String errMessage;
822
|
823 mike 1.53 //
824 // Get paths to data and index files:
825 //
826
827 String dataFilePath = _getInstanceDataFilePath(
828 nameSpace, newInstance.getClassName());
829
830 String indexFilePath = _getInstanceIndexFilePath(
831 nameSpace, newInstance.getClassName());
832
833 //
834 // Attempt rollback (if there are no rollback files, this will have no
835 // effect). This code is here to rollback uncommitted changes left over
836 // from last time an instance-oriented function was called.
837 //
838
839 if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
840 {
841 PEG_METHOD_EXIT();
842 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
843 }
844 mike 1.53
845 if (!InstanceDataFile::rollbackTransaction(dataFilePath))
846 {
847 PEG_METHOD_EXIT();
848 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
849 }
850
851 //
|
852 mike 1.54 // Resolve the instance. Looks up class and fills out properties but
853 // not the qualifiers.
|
854 mike 1.53 //
855
|
856 mike 1.51 CIMInstance cimInstance(newInstance);
|
857 mike 1.48 CIMConstClass cimClass;
|
858 mike 1.54 cimInstance.resolve(_context, nameSpace, cimClass, false);
|
859 kumpf 1.68 CIMObjectPath instanceName = cimInstance.getInstanceName(cimClass);
|
860 mike 1.48
|
861 mike 1.53 //
862 // Make sure the class has keys (otherwise it will be impossible to
863 // create the instance).
864 //
|
865 mike 1.48
866 if (!cimClass.hasKeys())
867 {
|
868 mike 1.51 errMessage = "class has no keys: ";
869 errMessage += cimClass.getClassName();
|
870 kumpf 1.52 PEG_METHOD_EXIT();
|
871 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
|
872 mike 1.48 }
873
|
874 mike 1.53 //
875 // Be sure instance does not already exist:
876 //
|
877 mike 1.48
878 String className;
879 Uint32 dummyIndex;
|
880 mike 1.51 Uint32 dummySize;
|
881 mike 1.48
|
882 mike 1.53 if (_getInstanceIndex(nameSpace, instanceName, className, dummyIndex,
883 dummySize, true))
|
884 mike 1.48 {
|
885 kumpf 1.52 PEG_METHOD_EXIT();
|
886 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ALREADY_EXISTS,
887 instanceName.toString());
|
888 mike 1.48 }
889
|
890 mike 1.53 //
891 // Create association entries if an association instance.
892 //
|
893 mike 1.48
894 if (cimClass.isAssociation())
|
895 mike 1.53 _createAssocInstEntries(nameSpace, cimClass, cimInstance, instanceName);
896
897 //
898 // Begin the transaction (any return prior to commit will cause
899 // a rollback next time an instance-oriented routine is invoked).
900 //
901
902 if (!InstanceIndexFile::beginTransaction(indexFilePath))
|
903 mike 1.48 {
|
904 mike 1.53 PEG_METHOD_EXIT();
905 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
|
906 mike 1.48 }
907
|
908 mike 1.53 if (!InstanceDataFile::beginTransaction(dataFilePath))
909 {
910 PEG_METHOD_EXIT();
911 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
912 }
|
913 mike 1.48
|
914 mike 1.53 //
915 // Save instance to file:
916 //
|
917 mike 1.51
918 Uint32 index;
919 Uint32 size;
|
920 mike 1.53
|
921 mike 1.51 {
|
922 mike 1.53 Array<Sint8> data;
|
923 kumpf 1.66 XmlWriter::appendInstanceElement(data, cimInstance);
|
924 mike 1.53 size = data.size();
925
926 if (!InstanceDataFile::appendInstance(dataFilePath, data, index))
927 {
928 errMessage.append("Failed to create instance: ");
929 errMessage.append(instanceName.toString());
930 PEG_METHOD_EXIT();
931 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
932 }
933 }
934
935 //
936 // Create entry in index file:
937 //
938
939 if (!InstanceIndexFile::createEntry(
940 indexFilePath, instanceName, index, size))
941 {
942 errMessage.append("Failed to create instance: ");
|
943 mike 1.51 errMessage.append(instanceName.toString());
|
944 kumpf 1.52 PEG_METHOD_EXIT();
|
945 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
946 }
|
947 mike 1.48
|
948 mike 1.53 //
949 // Commit the changes:
950 //
|
951 mike 1.48
|
952 mike 1.53 if (!InstanceIndexFile::commitTransaction(indexFilePath))
|
953 mike 1.51 {
|
954 kumpf 1.52 PEG_METHOD_EXIT();
|
955 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
|
956 mike 1.51 }
|
957 mike 1.48
|
958 mike 1.53 if (!InstanceDataFile::commitTransaction(dataFilePath))
|
959 mike 1.51 {
|
960 kumpf 1.52 PEG_METHOD_EXIT();
|
961 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
|
962 mike 1.51 }
|
963 mike 1.53
|
964 mike 1.54 cimInstance.resolve(_context, nameSpace, cimClass, true);
965
|
966 kumpf 1.52 PEG_METHOD_EXIT();
|
967 mike 1.53 return instanceName;
|
968 mike 1.48 }
969
970 void CIMRepository::modifyClass(
971 const String& nameSpace,
972 const CIMClass& modifiedClass)
973 {
|
974 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::modifyClass");
975
|
976 mike 1.53 //
977 // Resolve the class:
978 //
|
979 mike 1.51
|
980 mike 1.53 CIMClass cimClass(modifiedClass);
|
981 mike 1.48 cimClass.resolve(_context, nameSpace);
982
|
983 mike 1.53 //
984 // Check to see if it is okay to modify this class:
985 //
|
986 mike 1.48
987 String classFilePath;
988
989 _nameSpaceManager.checkModify(nameSpace, cimClass.getClassName(),
|
990 mike 1.51 cimClass.getSuperClassName(), classFilePath);
|
991 mike 1.48
|
992 mike 1.53 //
993 // ATTN: KS
994 // Disallow modification of classes which have instances (that are
995 // in the repository). And we have no idea whether the class has
996 // instances in other repositories or in providers. We should do
997 // an enumerate instance names at a higher level (above the repository).
998 //
999
1000 //
1001 // Delete the old file containing the class:
1002 //
|
1003 mike 1.48
1004 if (!FileSystem::removeFileNoCase(classFilePath))
1005 {
|
1006 kumpf 1.58 PEG_METHOD_EXIT();
|
1007 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
1008 "failed to remove file in CIMRepository::modifyClass()");
|
1009 mike 1.48 }
1010
|
1011 mike 1.53 //
1012 // Create new class file:
1013 //
|
1014 mike 1.48
|
1015 kumpf 1.66 Array<Sint8> classXml;
1016 XmlWriter::appendClassElement(classXml, cimClass);
1017 _SaveObject(classFilePath, classXml);
|
1018 kumpf 1.58
1019 PEG_METHOD_EXIT();
|
1020 mike 1.48 }
1021
1022 void CIMRepository::modifyInstance(
1023 const String& nameSpace,
|
1024 kumpf 1.70 const CIMInstance& modifiedInstance,
|
1025 mike 1.51 Boolean includeQualifiers,
1026 const CIMPropertyList& propertyList)
|
1027 mike 1.48 {
|
1028 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::modifyInstance");
1029
|
1030 mike 1.53 //
1031 // Get paths of index and data files:
1032 //
|
1033 mike 1.51
|
1034 kumpf 1.70 const CIMInstance& instance = modifiedInstance;
|
1035 mike 1.53
1036 String indexFilePath = _getInstanceIndexFilePath(
1037 nameSpace, instance.getClassName());
1038
1039 String dataFilePath = _getInstanceDataFilePath(
1040 nameSpace, instance.getClassName());
1041
1042 //
1043 // First attempt rollback:
1044 //
1045
1046 if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
|
1047 kumpf 1.58 {
1048 PEG_METHOD_EXIT();
|
1049 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
|
1050 kumpf 1.58 }
|
1051 mike 1.53
1052 if (!InstanceDataFile::rollbackTransaction(dataFilePath))
|
1053 kumpf 1.58 {
1054 PEG_METHOD_EXIT();
|
1055 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
|
1056 kumpf 1.58 }
|
1057 mike 1.53
1058 //
1059 // Begin the transaction:
1060 //
1061
1062 if (!InstanceIndexFile::beginTransaction(indexFilePath))
|
1063 kumpf 1.58 {
1064 PEG_METHOD_EXIT();
|
1065 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
|
1066 kumpf 1.58 }
|
1067 mike 1.53
1068 if (!InstanceDataFile::beginTransaction(dataFilePath))
|
1069 kumpf 1.61 {
|
1070 kumpf 1.58 PEG_METHOD_EXIT();
|
1071 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
|
1072 kumpf 1.58 }
|
1073 mike 1.53
1074 //
1075 // Do this:
1076 //
|
1077 mike 1.51
1078 String errMessage;
|
1079 mike 1.53 CIMInstance cimInstance; // The instance that replaces the original
|
1080 mike 1.51
1081 if (propertyList.isNull())
1082 {
1083 //
1084 // Replace all the properties in the instance
1085 //
1086 if (includeQualifiers)
1087 {
1088 //
1089 // Replace the entire instance with the given instance
1090 // (this is the default behavior)
1091 //
|
1092 kumpf 1.70 cimInstance = modifiedInstance;
|
1093 mike 1.51 }
1094 else
1095 {
1096 //
1097 // Replace all the properties in the instance, but keep the
1098 // original qualifiers on the instance and on the properties
1099 //
1100
|
1101 mike 1.55 _resolveInstance = false;
1102
1103 cimInstance = getInstance(
1104 nameSpace,
|
1105 kumpf 1.70 modifiedInstance.getPath (),
|
1106 mike 1.55 false,
1107 true,
1108 true);
1109
1110 _resolveInstance = true;
|
1111 mike 1.54
|
1112 mike 1.51 CIMInstance newInstance(
|
1113 kumpf 1.70 modifiedInstance.getPath ().getClassName());
|
1114 mike 1.54
|
1115 kumpf 1.70 CIMInstance givenInstance = modifiedInstance;
|
1116 mike 1.51
1117 //
1118 // Copy over the original instance qualifiers
1119 //
|
1120 mike 1.54
1121 for (Uint32 i = 0; i < cimInstance.getQualifierCount(); i++)
|
1122 mike 1.51 {
1123 newInstance.addQualifier(cimInstance.getQualifier(i));
1124 }
1125
1126 //
1127 // Loop through the properties replacing each property in the
1128 // original with a new value, but keeping the original qualifiers
1129 //
1130 for (Uint32 i=0; i<givenInstance.getPropertyCount(); i++)
1131 {
1132 // Copy the given property value (not qualifiers)
1133 CIMProperty givenProperty = givenInstance.getProperty(i);
1134 CIMProperty newProperty(
1135 givenProperty.getName(),
1136 givenProperty.getValue(),
1137 givenProperty.getArraySize(),
1138 givenProperty.getReferenceClassName(),
1139 givenProperty.getClassOrigin(),
1140 givenProperty.getPropagated());
1141
1142 // Copy the original property qualifiers
1143 mike 1.51 Uint32 origPos =
1144 cimInstance.findProperty(newProperty.getName());
1145 if (origPos != PEG_NOT_FOUND)
1146 {
1147 CIMProperty origProperty = cimInstance.getProperty(origPos);
1148 for (Uint32 j=0; j<origProperty.getQualifierCount(); j++)
1149 {
1150 newProperty.addQualifier(origProperty.getQualifier(i));
1151 }
1152 }
1153
1154 // Add the newly constructed property to the new instance
1155 newInstance.addProperty(newProperty);
1156 }
1157
1158 // Use the newly merged instance to replace the original instance
1159 cimInstance = newInstance;
1160 }
1161 }
1162 else
1163 {
1164 mike 1.51 //
1165 // Replace only the properties specified in the given instance
1166 //
1167
|
1168 mike 1.55 _resolveInstance = false;
1169
|
1170 mike 1.51 cimInstance = getInstance(nameSpace,
|
1171 kumpf 1.70 modifiedInstance.getPath (), false, true, true);
|
1172 mike 1.55
1173 _resolveInstance = true;
1174
|
1175 kumpf 1.70 CIMInstance givenInstance = modifiedInstance;
|
1176 mike 1.51
1177 // NOTE: Instance qualifiers are not changed when a property list
1178 // is specified. Property qualifiers are replaced with the
1179 // corresponding property values.
1180
1181 //
1182 // Loop through the propertyList replacing each property in the original
1183 //
|
1184 mike 1.53
|
1185 mike 1.51 for (Uint32 i=0; i<propertyList.getNumProperties(); i++)
1186 {
1187 Uint32 origPropPos =
1188 cimInstance.findProperty(propertyList.getPropertyName(i));
1189 if (origPropPos != PEG_NOT_FOUND)
1190 {
1191 // Case: Property set in original
1192 CIMProperty origProperty =
1193 cimInstance.getProperty(origPropPos);
1194
1195 // Get the given property value
1196 Uint32 givenPropPos =
1197 givenInstance.findProperty(propertyList.getPropertyName(i));
1198 if (givenPropPos != PEG_NOT_FOUND)
1199 {
1200 // Case: Property set in original and given
1201 CIMProperty givenProperty =
1202 givenInstance.getProperty(givenPropPos);
1203
1204 // Copy over the property from the given to the original
1205 if (includeQualifiers)
1206 mike 1.51 {
1207 // Case: Total property replacement
1208 cimInstance.removeProperty(origPropPos);
1209 cimInstance.addProperty(givenProperty);
1210 }
1211 else
1212 {
1213 // Case: Replace only the property value (not quals)
1214 origProperty.setValue(givenProperty.getValue());
1215 cimInstance.removeProperty(origPropPos);
1216 cimInstance.addProperty(origProperty);
1217 }
1218 }
1219 else
1220 {
1221 // Case: Property set in original and not in given
1222 // Just remove the property (set to null)
1223 cimInstance.removeProperty(origPropPos);
1224 }
1225 }
1226 else
1227 mike 1.51 {
1228 // Case: Property not set in original
1229
1230 // Get the given property value
1231 Uint32 givenPropPos =
1232 givenInstance.findProperty(propertyList.getPropertyName(i));
1233 if (givenPropPos != PEG_NOT_FOUND)
1234 {
1235 // Case: Property set in given and not in original
1236 CIMProperty givenProperty =
1237 givenInstance.getProperty(givenPropPos);
1238
1239 // Copy over the property from the given to the original
1240 if (includeQualifiers)
1241 {
1242 // Case: Total property copy
1243 cimInstance.addProperty(givenProperty);
1244 }
1245 else
1246 {
1247 // Case: Copy only the property value (not qualifiers)
1248 mike 1.51 CIMProperty newProperty(
1249 givenProperty.getName(),
1250 givenProperty.getValue(),
1251 givenProperty.getArraySize(),
1252 givenProperty.getReferenceClassName(),
1253 givenProperty.getClassOrigin(),
1254 givenProperty.getPropagated());
1255 cimInstance.addProperty(newProperty);
1256 }
1257 }
1258 else
1259 {
1260 // Case: Property not set in original or in given
1261
1262 // Nothing to do; just make sure the property name is valid
1263 // ATTN: This is not the most efficient solution
1264 CIMClass cimClass = getClass(
1265 nameSpace, cimInstance.getClassName(), false);
1266 if (!cimClass.existsProperty(
1267 propertyList.getPropertyName(i)))
1268 {
1269 mike 1.51 // ATTN: This exception may be returned by setProperty
|
1270 kumpf 1.58 PEG_METHOD_EXIT();
|
1271 mike 1.51 throw PEGASUS_CIM_EXCEPTION(
1272 CIM_ERR_NO_SUCH_PROPERTY, "modifyInstance()");
1273 }
1274 }
1275 }
1276 }
1277 }
1278
|
1279 mike 1.53 //
|
1280 mike 1.54 // Resolve the instance (do not propagate qualifiers from class since
1281 // this will bloat the instance).
|
1282 mike 1.53 //
|
1283 mike 1.48
1284 CIMConstClass cimClass;
|
1285 mike 1.54 cimInstance.resolve(_context, nameSpace, cimClass, false);
|
1286 mike 1.48
|
1287 kumpf 1.68 CIMObjectPath instanceName = cimInstance.getInstanceName(cimClass);
|
1288 mike 1.51
|
1289 mike 1.53 //
1290 // Disallow operation if the instance name was changed:
1291 //
|
1292 mike 1.51
|
1293 kumpf 1.70 if (instanceName != modifiedInstance.getPath ())
|
1294 mike 1.51 {
|
1295 kumpf 1.58 PEG_METHOD_EXIT();
|
1296 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
1297 "Attempted to modify a key property");
1298 }
1299
1300 Uint32 oldSize;
1301 Uint32 oldIndex;
1302 Uint32 newSize;
1303 Uint32 newIndex;
|
1304 mike 1.48
|
1305 mike 1.53 if (!InstanceIndexFile::lookupEntry(
1306 indexFilePath, instanceName, oldIndex, oldSize))
|
1307 mike 1.51 {
|
1308 kumpf 1.58 PEG_METHOD_EXIT();
|
1309 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
1310 }
|
1311 mike 1.48
|
1312 mike 1.53 //
1313 // Modify the data file:
1314 //
1315
1316 {
1317 Array<Sint8> out;
|
1318 kumpf 1.66 XmlWriter::appendInstanceElement(out, cimInstance);
|
1319 mike 1.48
|
1320 mike 1.53 newSize = out.size();
|
1321 mike 1.48
|
1322 mike 1.53 if (!InstanceDataFile::appendInstance(dataFilePath, out, newIndex))
1323 {
1324 errMessage.append("Failed to modify instance ");
1325 errMessage.append(instanceName.toString());
|
1326 kumpf 1.58 PEG_METHOD_EXIT();
|
1327 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1328 }
|
1329 mike 1.48 }
1330
|
1331 mike 1.53 //
1332 // Modify the index file:
1333 //
1334
1335 Uint32 freeCount;
|
1336 mike 1.51
|
1337 mike 1.53 if (!InstanceIndexFile::modifyEntry(indexFilePath, instanceName, newIndex,
1338 newSize, freeCount))
|
1339 mike 1.51 {
1340 errMessage.append("Failed to modify instance ");
1341 errMessage.append(instanceName.toString());
|
1342 kumpf 1.58 PEG_METHOD_EXIT();
|
1343 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1344 }
1345
|
1346 mike 1.53 //
1347 // Commit the transaction:
1348 //
1349
1350 if (!InstanceIndexFile::commitTransaction(indexFilePath))
|
1351 kumpf 1.58 {
1352 PEG_METHOD_EXIT();
|
1353 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
|
1354 kumpf 1.58 }
|
1355 mike 1.53
1356 if (!InstanceDataFile::commitTransaction(dataFilePath))
|
1357 kumpf 1.58 {
1358 PEG_METHOD_EXIT();
|
1359 mike 1.53 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
|
1360 kumpf 1.58 }
|
1361 mike 1.48
|
1362 mike 1.53 //
1363 // Compact the index and data files if the free count max was
1364 // reached.
1365 //
1366
1367 if (freeCount == _MAX_FREE_COUNT)
1368 _CompactInstanceRepository(indexFilePath, dataFilePath);
|
1369 mike 1.54
1370 //
1371 // Resolve the instance:
1372 //
1373
1374 cimInstance.resolve(_context, nameSpace, cimClass, true);
|
1375 kumpf 1.58
1376 PEG_METHOD_EXIT();
|
1377 mike 1.48 }
1378
1379 Array<CIMClass> CIMRepository::enumerateClasses(
1380 const String& nameSpace,
1381 const String& className,
1382 Boolean deepInheritance,
1383 Boolean localOnly,
1384 Boolean includeQualifiers,
1385 Boolean includeClassOrigin)
1386 {
|
1387 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateClasses");
|
1388 mike 1.51
|
1389 mike 1.48 Array<String> classNames;
1390
1391 _nameSpaceManager.getSubClassNames(
|
1392 mike 1.51 nameSpace, className, deepInheritance, classNames);
|
1393 mike 1.48
1394 Array<CIMClass> result;
1395
1396 for (Uint32 i = 0; i < classNames.size(); i++)
1397 {
|
1398 mike 1.51 result.append(getClass(nameSpace, classNames[i], localOnly,
1399 includeQualifiers, includeClassOrigin));
|
1400 mike 1.48 }
1401
|
1402 kumpf 1.58 PEG_METHOD_EXIT();
|
1403 mike 1.48 return result;
1404 }
1405
1406 Array<String> CIMRepository::enumerateClassNames(
1407 const String& nameSpace,
1408 const String& className,
1409 Boolean deepInheritance)
1410 {
|
1411 kumpf 1.59 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateClassNames");
|
1412 kumpf 1.58
|
1413 mike 1.48 Array<String> classNames;
1414
1415 _nameSpaceManager.getSubClassNames(
|
1416 mike 1.51 nameSpace, className, deepInheritance, classNames);
|
1417 mike 1.48
|
1418 kumpf 1.58 PEG_METHOD_EXIT();
|
1419 mike 1.48 return classNames;
1420 }
1421
|
1422 mike 1.53 Boolean CIMRepository::_loadAllInstances(
1423 const String& nameSpace,
1424 const String& className,
|
1425 kumpf 1.70 Array<CIMInstance>& namedInstances)
|
1426 mike 1.53 {
|
1427 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_loadAllInstances");
1428
|
1429 kumpf 1.68 Array<CIMObjectPath> instanceNames;
|
1430 mike 1.53 Array<Sint8> data;
1431 Array<Uint32> indices;
1432 Array<Uint32> sizes;
1433
1434 //
1435 // Form the name of the instance index file
1436 //
1437
1438 String indexFilePath = _getInstanceIndexFilePath(nameSpace, className);
1439
1440 //
1441 // Form the name of the instance file
1442 //
1443
1444 String dataFilePath = _getInstanceDataFilePath(nameSpace, className);
1445
1446 //
1447 // Enumerate the index file:
1448 //
1449
1450 Array<Uint32> freeFlags;
1451 mike 1.53
1452 if (!InstanceIndexFile::enumerateEntries(
1453 indexFilePath, freeFlags, indices, sizes, instanceNames, true))
1454 {
|
1455 kumpf 1.58 PEG_METHOD_EXIT();
|
1456 mike 1.53 return false;
1457 }
1458
1459 //
1460 // Form the array of instances result:
1461 //
1462
1463 if (instanceNames.size() > 0)
1464 {
1465 //
1466 // Load all instances from the data file:
1467 //
1468
1469 if (!InstanceDataFile::loadAllInstances(dataFilePath, data))
|
1470 kumpf 1.58 {
1471 PEG_METHOD_EXIT();
|
1472 mike 1.53 return false;
|
1473 kumpf 1.58 }
|
1474 mike 1.53
1475 //
1476 // for each instance loaded, call XML parser to parse the XML
1477 // data and create a CIMInstance object.
1478 //
1479
1480 CIMInstance tmpInstance;
1481
1482 Uint32 bufferSize = data.size();
1483 char* buffer = (char*)data.getData();
1484
1485 for (Uint32 i = 0; i < instanceNames.size(); i++)
1486 {
1487 if (!freeFlags[i])
1488 {
1489 XmlParser parser(&(buffer[indices[i]]));
1490
1491 XmlReader::getObject(parser, tmpInstance);
1492
|
1493 mike 1.54 tmpInstance.resolve(_context, nameSpace, true);
|
1494 kumpf 1.70 tmpInstance.setPath (instanceNames[i]);
|
1495 mike 1.54
|
1496 kumpf 1.70 namedInstances.append (tmpInstance);
|
1497 mike 1.53 }
1498 }
1499 }
1500
|
1501 kumpf 1.58 PEG_METHOD_EXIT();
|
1502 mike 1.53 return true;
1503 }
1504
|
1505 kumpf 1.70 Array<CIMInstance> CIMRepository::enumerateInstances(
|
1506 mike 1.48 const String& nameSpace,
1507 const String& className,
1508 Boolean deepInheritance,
1509 Boolean localOnly,
1510 Boolean includeQualifiers,
1511 Boolean includeClassOrigin,
|
1512 mike 1.51 const CIMPropertyList& propertyList)
|
1513 mike 1.48 {
|
1514 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateInstances");
|
1515 karl 1.69 //
1516 // Get all descendent classes of this class:
1517 //
1518
1519 Array<String> classNames;
1520 //ATTN: Should this be protected with a try block KS 15 May 2002 P0
1521 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
1522 classNames.prepend(className);
1523
1524 //
1525 // Get all instances for this class and all its descendent classes
1526 //
|
1527 kumpf 1.58
|
1528 kumpf 1.70 Array<CIMInstance> namedInstances;
|
1529 karl 1.69
1530 for (Uint32 i = 0; i < classNames.size(); i++)
|
1531 karl 1.65 {
|
1532 karl 1.69 if (!_loadAllInstances(nameSpace, classNames[i], namedInstances))
1533 {
1534 String errMessage = "Failed to load instances in class ";
1535 errMessage.append(classNames[i]);
1536 PEG_METHOD_EXIT();
1537 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1538 }
|
1539 karl 1.65 }
|
1540 karl 1.69
|
1541 karl 1.65 PEG_METHOD_EXIT();
1542 return namedInstances;
|
1543 karl 1.69 }
|
1544 karl 1.65
|
1545 kumpf 1.70 Array<CIMInstance> CIMRepository::enumerateInstancesForClass(
|
1546 karl 1.69 const String& nameSpace,
1547 const String& className,
1548 Boolean deepInheritance,
1549 Boolean localOnly,
1550 Boolean includeQualifiers,
1551 Boolean includeClassOrigin,
1552 Boolean includeInheritance,
1553 const CIMPropertyList& propertyList)
1554 {
1555 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateInstances");
|
1556 mike 1.53 //
1557 // Get all descendent classes of this class:
1558 //
|
1559 mike 1.48
1560 Array<String> classNames;
|
1561 karl 1.69 // If includeInheritance is true, get all subclasses.
1562 // ATTN: P3 KS Look at whether the subclassNames requires an empty array.
1563 if(includeInheritance)
1564 {
1565 try
1566 {
1567 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
1568 }
1569 catch(CIMException& e)
1570 {
1571 PEG_METHOD_EXIT();
1572 throw e;
1573 }
1574 }
|
1575 mike 1.48 classNames.prepend(className);
1576
|
1577 mike 1.53 //
1578 // Get all instances for this class and all its descendent classes
1579 //
|
1580 mike 1.48
|
1581 kumpf 1.70 Array<CIMInstance> namedInstances;
|
1582 karl 1.69
|
1583 mike 1.48 for (Uint32 i = 0; i < classNames.size(); i++)
1584 {
|
1585 mike 1.51 if (!_loadAllInstances(nameSpace, classNames[i], namedInstances))
1586 {
1587 String errMessage = "Failed to load instances in class ";
1588 errMessage.append(classNames[i]);
|
1589 kumpf 1.58 PEG_METHOD_EXIT();
|
1590 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1591 }
|
1592 mike 1.48 }
|
1593 karl 1.69
|
1594 kumpf 1.58 PEG_METHOD_EXIT();
|
1595 mike 1.51 return namedInstances;
|
1596 mike 1.48 }
|
1597 kumpf 1.68 Array<CIMObjectPath> CIMRepository::enumerateInstanceNames(
|
1598 mike 1.48 const String& nameSpace,
1599 const String& className)
1600 {
|
1601 kumpf 1.61 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateInstanceNames");
|
1602 mike 1.51
|
1603 karl 1.65 //
|
1604 karl 1.69 // Get names of descendent classes:
|
1605 karl 1.65 //
|
1606 karl 1.69 Array<String> classNames;
1607
1608 try
1609 {
1610 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
1611 }
1612 catch(CIMException& e)
1613 {
1614 PEG_METHOD_EXIT();
1615 throw e;
1616 }
1617 classNames.prepend(className);
|
1618 karl 1.65
1619 //
|
1620 karl 1.69 // Get instance names from each qualifying instance file for the class:
|
1621 karl 1.65 //
|
1622 karl 1.69 Array<CIMObjectPath> instanceNames;
1623 Array<Uint32> indices;
1624 Array<Uint32> sizes;
|
1625 karl 1.65
|
1626 karl 1.69 for (Uint32 i = 0; i < classNames.size(); i++)
1627 {
1628 //
1629 // Form the name of the class index file:
1630 //
1631
1632 String indexFilePath = _getInstanceIndexFilePath(
1633 nameSpace, classNames[i]);
1634
1635 //
1636 // Get all instances for that class:
1637 //
1638
1639 Array<Uint32> freeFlags;
|
1640 karl 1.65
|
1641 karl 1.69 if (!InstanceIndexFile::enumerateEntries(
1642 indexFilePath, freeFlags, indices, sizes, instanceNames, false))
1643 {
1644 String errMessage = "Failed to load instance names in class ";
1645 errMessage.append(classNames[i]);
1646 PEG_METHOD_EXIT();
1647 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1648 }
|
1649 karl 1.65 }
1650
|
1651 karl 1.69 PEG_METHOD_EXIT();
1652 return instanceNames;
1653 }
1654
1655 Array<CIMObjectPath> CIMRepository::enumerateInstanceNamesForClass(
1656 const String& nameSpace,
1657 const String& className,
1658 Boolean includeInheritance)
1659 {
1660 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateInstanceNames");
1661
|
1662 mike 1.53 //
1663 // Get names of descendent classes:
1664 //
|
1665 mike 1.48 Array<String> classNames;
|
1666 karl 1.69
1667 // If includeInheritance is true, get all subclasses.
1668 if(includeInheritance)
|
1669 mday 1.57 {
|
1670 karl 1.69 try
1671 {
1672 _nameSpaceManager.getSubClassNames(nameSpace, className, true, classNames);
1673 }
1674 catch(CIMException& e)
1675 {
1676 PEG_METHOD_EXIT();
1677 throw e;
1678 }
|
1679 mday 1.57 }
|
1680 mike 1.48 classNames.prepend(className);
1681
|
1682 mike 1.53 //
1683 // Get instance names from each qualifying instance file for the class:
1684 //
|
1685 kumpf 1.68 Array<CIMObjectPath> instanceNames;
|
1686 mike 1.48 Array<Uint32> indices;
|
1687 mike 1.51 Array<Uint32> sizes;
|
1688 mike 1.48
1689 for (Uint32 i = 0; i < classNames.size(); i++)
1690 {
|
1691 mike 1.53 //
1692 // Form the name of the class index file:
1693 //
|
1694 mike 1.48
|
1695 mike 1.53 String indexFilePath = _getInstanceIndexFilePath(
1696 nameSpace, classNames[i]);
|
1697 mike 1.48
|
1698 mike 1.53 //
|
1699 mike 1.51 // Get all instances for that class:
|
1700 mike 1.53 //
1701
1702 Array<Uint32> freeFlags;
|
1703 mike 1.48
|
1704 mike 1.53 if (!InstanceIndexFile::enumerateEntries(
1705 indexFilePath, freeFlags, indices, sizes, instanceNames, false))
|
1706 mike 1.51 {
1707 String errMessage = "Failed to load instance names in class ";
|
1708 mike 1.53 errMessage.append(classNames[i]);
|
1709 kumpf 1.52 PEG_METHOD_EXIT();
|
1710 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, errMessage);
1711 }
|
1712 mike 1.48 }
|
1713 mike 1.53
|
1714 kumpf 1.52 PEG_METHOD_EXIT();
|
1715 mike 1.48 return instanceNames;
1716 }
|
1717 karl 1.69
|
1718 mike 1.48
1719 Array<CIMInstance> CIMRepository::execQuery(
1720 const String& queryLanguage,
1721 const String& query)
1722 {
|
1723 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::execQuery");
1724
1725 PEG_METHOD_EXIT();
|
1726 mike 1.48 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, "execQuery()");
1727
|
1728 kumpf 1.58 PEG_METHOD_EXIT();
|
1729 mike 1.48 return Array<CIMInstance>();
1730 }
1731
|
1732 kumpf 1.71 Array<CIMObject> CIMRepository::associators(
|
1733 mike 1.48 const String& nameSpace,
|
1734 kumpf 1.68 const CIMObjectPath& objectName,
|
1735 mike 1.48 const String& assocClass,
1736 const String& resultClass,
1737 const String& role,
1738 const String& resultRole,
1739 Boolean includeQualifiers,
1740 Boolean includeClassOrigin,
|
1741 mike 1.51 const CIMPropertyList& propertyList)
|
1742 mike 1.48 {
|
1743 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::associators");
1744
|
1745 kumpf 1.68 Array<CIMObjectPath> names = associatorNames(
|
1746 mike 1.51 nameSpace,
1747 objectName,
1748 assocClass,
1749 resultClass,
1750 role,
1751 resultRole);
|
1752 mike 1.48
|
1753 kumpf 1.71 Array<CIMObject> result;
|
1754 mike 1.48
1755 for (Uint32 i = 0, n = names.size(); i < n; i++)
1756 {
|
1757 mike 1.51 String tmpNameSpace = names[i].getNameSpace();
|
1758 mike 1.48
|
1759 mike 1.51 if (tmpNameSpace.size() == 0)
1760 tmpNameSpace = nameSpace;
|
1761 mike 1.48
|
1762 mike 1.51 if (names[i].isClassName())
1763 {
|
1764 kumpf 1.68 CIMObjectPath tmpRef = names[i];
|
1765 mike 1.51 tmpRef.setHost(String());
1766 tmpRef.setNameSpace(String());
1767
1768 CIMClass cimClass = getClass(
1769 tmpNameSpace,
1770 tmpRef.getClassName(),
1771 false,
1772 includeQualifiers,
1773 includeClassOrigin,
1774 propertyList);
1775
1776 CIMObject cimObject(cimClass);
|
1777 kumpf 1.71 cimObject.setPath (names[i]);
1778 result.append(cimObject);
|
1779 mike 1.51 }
1780 else
1781 {
|
1782 kumpf 1.68 CIMObjectPath tmpRef = names[i];
|
1783 mike 1.51 tmpRef.setHost(String());
1784 tmpRef.setNameSpace(String());
1785
1786 CIMInstance cimInstance = getInstance(
1787 tmpNameSpace,
1788 tmpRef,
1789 false,
1790 includeQualifiers,
1791 includeClassOrigin,
1792 propertyList);
1793
1794 CIMObject cimObject(cimInstance);
|
1795 kumpf 1.71 cimObject.setPath (names[i]);
1796 result.append(cimObject);
|
1797 mike 1.51 }
|
1798 mike 1.48 }
1799
|
1800 kumpf 1.58 PEG_METHOD_EXIT();
|
1801 mike 1.48 return result;
1802 }
1803
|
1804 kumpf 1.68 Array<CIMObjectPath> CIMRepository::associatorNames(
|
1805 mike 1.48 const String& nameSpace,
|
1806 kumpf 1.68 const CIMObjectPath& objectName,
|
1807 mike 1.48 const String& assocClass,
1808 const String& resultClass,
1809 const String& role,
1810 const String& resultRole)
1811 {
|
1812 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::associatorNames");
|
1813 mike 1.51
|
1814 mike 1.48 Array<String> associatorNames;
1815
1816 if (objectName.isClassName())
1817 {
|
1818 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
1819 mike 1.48
|
1820 mike 1.51 AssocClassTable::getAssociatorNames(
1821 assocFileName,
1822 objectName.toString(),
1823 assocClass,
1824 resultClass,
1825 role,
1826 resultRole,
1827 associatorNames);
|
1828 mike 1.48 }
1829 else
1830 {
|
1831 mike 1.51 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
|
1832 mike 1.48
|
1833 mike 1.51 AssocInstTable::getAssociatorNames(
1834 assocFileName,
1835 objectName,
1836 assocClass,
1837 resultClass,
1838 role,
1839 resultRole,
1840 associatorNames);
|
1841 mike 1.48 }
1842
|
1843 kumpf 1.68 Array<CIMObjectPath> result;
|
1844 mike 1.48
1845 for (Uint32 i = 0, n = associatorNames.size(); i < n; i++)
1846 {
|
1847 kumpf 1.68 CIMObjectPath r = associatorNames[i];
|
1848 mike 1.48
1849 if (r.getHost().size() == 0)
1850 r.setHost(System::getHostName());
1851
1852 if (r.getNameSpace().size() == 0)
1853 r.setNameSpace(nameSpace);
1854
|
1855 mike 1.51 result.append(r);
|
1856 mike 1.48 }
1857
|
1858 kumpf 1.58 PEG_METHOD_EXIT();
|
1859 mike 1.48 return result;
1860 }
1861
|
1862 kumpf 1.71 Array<CIMObject> CIMRepository::references(
|
1863 mike 1.48 const String& nameSpace,
|
1864 kumpf 1.68 const CIMObjectPath& objectName,
|
1865 mike 1.48 const String& resultClass,
1866 const String& role,
1867 Boolean includeQualifiers,
1868 Boolean includeClassOrigin,
|
1869 mike 1.51 const CIMPropertyList& propertyList)
|
1870 mike 1.48 {
|
1871 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::references");
1872
|
1873 kumpf 1.68 Array<CIMObjectPath> names = referenceNames(
|
1874 mike 1.51 nameSpace,
1875 objectName,
1876 resultClass,
1877 role);
|
1878 mike 1.48
|
1879 kumpf 1.71 Array<CIMObject> result;
|
1880 mike 1.48
1881 for (Uint32 i = 0, n = names.size(); i < n; i++)
1882 {
|
1883 mike 1.51 String tmpNameSpace = names[i].getNameSpace();
|
1884 mike 1.48
|
1885 mike 1.51 if (tmpNameSpace.size() == 0)
1886 tmpNameSpace = nameSpace;
|
1887 mike 1.48
|
1888 mike 1.51 // ATTN: getInstance() should this be able to handle instance names
1889 // with host names and namespaces?
|
1890 mike 1.48
|
1891 kumpf 1.68 CIMObjectPath tmpRef = names[i];
|
1892 mike 1.51 tmpRef.setHost(String());
1893 tmpRef.setNameSpace(String());
1894
1895 if (objectName.isClassName())
1896 {
1897 CIMClass cimClass = getClass(
1898 tmpNameSpace,
1899 tmpRef.getClassName(),
1900 false,
1901 includeQualifiers,
1902 includeClassOrigin,
1903 propertyList);
1904
|
1905 kumpf 1.71 CIMObject cimObject = CIMObject (cimClass);
1906 cimObject.setPath (names[i]);
1907 result.append (cimObject);
|
1908 mike 1.51 }
1909 else
1910 {
1911 CIMInstance instance = getInstance(
1912 tmpNameSpace,
1913 tmpRef,
1914 false,
1915 includeQualifiers,
1916 includeClassOrigin,
1917 propertyList);
|
1918 mike 1.48
|
1919 kumpf 1.71 CIMObject cimObject = CIMObject (instance);
1920 cimObject.setPath (names[i]);
1921 result.append (cimObject);
|
1922 mike 1.51 }
|
1923 mike 1.48 }
1924
|
1925 kumpf 1.58 PEG_METHOD_EXIT();
|
1926 mike 1.48 return result;
1927 }
1928
|
1929 kumpf 1.68 Array<CIMObjectPath> CIMRepository::referenceNames(
|
1930 mike 1.48 const String& nameSpace,
|
1931 kumpf 1.68 const CIMObjectPath& objectName,
|
1932 mike 1.48 const String& resultClass,
1933 const String& role)
1934 {
|
1935 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::referenceNames");
1936
|
1937 mike 1.48 Array<String> tmpReferenceNames;
1938
1939 if (objectName.isClassName())
1940 {
|
1941 mike 1.51 String assocFileName = _MakeAssocClassPath(nameSpace, _repositoryRoot);
|
1942 mike 1.48
|
1943 mike 1.51 if (!AssocClassTable::getReferenceNames(
1944 assocFileName,
1945 objectName.getClassName(),
1946 resultClass,
1947 role,
1948 tmpReferenceNames))
1949 {
1950 // Ignore error! It's okay not to have references.
1951 }
|
1952 mike 1.48 }
1953 else
1954 {
|
1955 mike 1.51 String assocFileName = _MakeAssocInstPath(nameSpace, _repositoryRoot);
|
1956 mike 1.48
|
1957 mike 1.51 if (!AssocInstTable::getReferenceNames(
1958 assocFileName,
1959 objectName,
1960 resultClass,
1961 role,
1962 tmpReferenceNames))
1963 {
1964 // Ignore error! It's okay not to have references.
1965 }
|
1966 mike 1.48 }
1967
|
1968 kumpf 1.68 Array<CIMObjectPath> result;
|
1969 mike 1.48
1970 for (Uint32 i = 0, n = tmpReferenceNames.size(); i < n; i++)
1971 {
|
1972 kumpf 1.68 CIMObjectPath r = tmpReferenceNames[i];
|
1973 mike 1.48
1974 if (r.getHost().size() == 0)
1975 r.setHost(System::getHostName());
1976
1977 if (r.getNameSpace().size() == 0)
1978 r.setNameSpace(nameSpace);
1979
|
1980 mike 1.51 result.append(r);
|
1981 mike 1.48 }
1982
|
1983 kumpf 1.58 PEG_METHOD_EXIT();
|
1984 mike 1.48 return result;
1985 }
1986
1987 CIMValue CIMRepository::getProperty(
1988 const String& nameSpace,
|
1989 kumpf 1.68 const CIMObjectPath& instanceName,
|
1990 mike 1.48 const String& propertyName)
1991 {
|
1992 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::getProperty");
1993
|
1994 mike 1.53 //
1995 // Get the index for this instance:
1996 //
|
1997 mike 1.48
1998 String className;
1999 Uint32 index;
|
2000 mike 1.51 Uint32 size;
|
2001 mike 1.48
|
2002 mike 1.53 if (!_getInstanceIndex(nameSpace, instanceName, className, index, size))
|
2003 kumpf 1.58 {
2004 PEG_METHOD_EXIT();
|
2005 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
|
2006 kumpf 1.58 }
|
2007 mike 1.48
|
2008 mike 1.53 //
2009 // Load the instance into memory:
2010 //
|
2011 mike 1.48
|
2012 mike 1.53 String path = _getInstanceDataFilePath(nameSpace, className);
|
2013 mike 1.48 CIMInstance cimInstance;
|
2014 mike 1.53
|
2015 mike 1.51 if (!_loadInstance(path, cimInstance, index, size))
2016 {
|
2017 kumpf 1.58 PEG_METHOD_EXIT();
|
2018 mike 1.51 throw CannotOpenFile(path);
2019 }
|
2020 mike 1.48
|
2021 mike 1.53 //
2022 // Grab the property from the instance:
2023 //
|
2024 mike 1.48
2025 Uint32 pos = cimInstance.findProperty(propertyName);
2026
|
2027 mike 1.51 // ATTN: This breaks if the property is simply null
|
2028 mike 1.48 if (pos == PEGASUS_NOT_FOUND)
|
2029 kumpf 1.58 {
2030 PEG_METHOD_EXIT();
|
2031 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NO_SUCH_PROPERTY, "getProperty()");
|
2032 kumpf 1.58 }
|
2033 mike 1.48
2034 CIMProperty prop = cimInstance.getProperty(pos);
2035
|
2036 mike 1.53 //
2037 // Return the value:
2038 //
|
2039 mike 1.48
|
2040 kumpf 1.58 PEG_METHOD_EXIT();
|
2041 mike 1.48 return prop.getValue();
2042 }
2043
2044 void CIMRepository::setProperty(
2045 const String& nameSpace,
|
2046 kumpf 1.68 const CIMObjectPath& instanceName,
|
2047 mike 1.48 const String& propertyName,
2048 const CIMValue& newValue)
2049 {
|
2050 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::setProperty");
2051
|
2052 mike 1.51 //
2053 // Create the instance to pass to modifyInstance()
2054 //
|
2055 mike 1.53
|
2056 mike 1.51 CIMInstance instance(instanceName.getClassName());
2057 instance.addProperty(CIMProperty(propertyName, newValue));
|
2058 kumpf 1.70 instance.setPath (instanceName);
|
2059 mike 1.51
2060 //
2061 // Create the propertyList to pass to modifyInstance()
2062 //
|
2063 mike 1.53
|
2064 mike 1.51 Array<String> propertyListArray;
2065 propertyListArray.append(propertyName);
2066 CIMPropertyList propertyList(propertyListArray);
2067
2068 //
2069 // Modify the instance to set the value of the given property
2070 //
|
2071 kumpf 1.70 modifyInstance(nameSpace, instance, false, propertyList);
|
2072 kumpf 1.58
2073 PEG_METHOD_EXIT();
|
2074 mike 1.48 }
2075
2076 CIMQualifierDecl CIMRepository::getQualifier(
2077 const String& nameSpace,
2078 const String& qualifierName)
2079 {
|
2080 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::getQualifier");
2081
|
2082 mike 1.53 //
2083 // Get path of qualifier file:
2084 //
|
2085 mike 1.48
2086 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
2087 mike 1.51 nameSpace, qualifierName);
|
2088 mike 1.48
|
2089 mike 1.53 //
2090 // Load qualifier:
2091 //
|
2092 mike 1.48
2093 CIMQualifierDecl qualifierDecl;
2094
2095 try
2096 {
|
2097 mike 1.51 _LoadObject(qualifierFilePath, qualifierDecl);
|
2098 mike 1.48 }
2099 catch (CannotOpenFile&)
2100 {
|
2101 kumpf 1.58 PEG_METHOD_EXIT();
|
2102 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, qualifierName);
|
2103 mike 1.48 }
2104
|
2105 kumpf 1.58 PEG_METHOD_EXIT();
|
2106 mike 1.48 return qualifierDecl;
2107 }
2108
2109 void CIMRepository::setQualifier(
2110 const String& nameSpace,
2111 const CIMQualifierDecl& qualifierDecl)
2112 {
|
2113 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::setQualifier");
2114
|
2115 mike 1.48 // -- Get path of qualifier file:
2116
2117 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
2118 mike 1.51 nameSpace, qualifierDecl.getName());
|
2119 mike 1.48
2120 // -- If qualifier alread exists, throw exception:
2121
2122 if (FileSystem::existsNoCase(qualifierFilePath))
|
2123 mike 1.53 {
|
2124 kumpf 1.58 PEG_METHOD_EXIT();
|
2125 mike 1.53 throw PEGASUS_CIM_EXCEPTION(
2126 CIM_ERR_ALREADY_EXISTS, qualifierDecl.getName());
2127 }
|
2128 mike 1.48
2129 // -- Save qualifier:
2130
|
2131 kumpf 1.66 Array<Sint8> qualifierDeclXml;
|
2132 kumpf 1.67 XmlWriter::appendQualifierDeclElement(qualifierDeclXml, qualifierDecl);
|
2133 kumpf 1.66 _SaveObject(qualifierFilePath, qualifierDeclXml);
|
2134 kumpf 1.58
2135 PEG_METHOD_EXIT();
|
2136 mike 1.48 }
2137
2138 void CIMRepository::deleteQualifier(
2139 const String& nameSpace,
2140 const String& qualifierName)
2141 {
|
2142 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::deleteQualifier");
2143
|
2144 mike 1.48 // -- Get path of qualifier file:
2145
2146 String qualifierFilePath = _nameSpaceManager.getQualifierFilePath(
|
2147 mike 1.51 nameSpace, qualifierName);
|
2148 mike 1.48
2149 // -- Delete qualifier:
2150
2151 if (!FileSystem::removeFileNoCase(qualifierFilePath))
|
2152 kumpf 1.58 {
2153 PEG_METHOD_EXIT();
|
2154 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, qualifierName);
|
2155 kumpf 1.58 }
2156
2157 PEG_METHOD_EXIT();
|
2158 mike 1.48 }
2159
2160 Array<CIMQualifierDecl> CIMRepository::enumerateQualifiers(
2161 const String& nameSpace)
2162 {
|
2163 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateQualifiers");
2164
|
2165 mike 1.48 String qualifiersRoot = _nameSpaceManager.getQualifiersRoot(nameSpace);
2166
2167 Array<String> qualifierNames;
2168
2169 if (!FileSystem::getDirectoryContents(qualifiersRoot, qualifierNames))
2170 {
|
2171 kumpf 1.58 PEG_METHOD_EXIT();
|
2172 mike 1.51 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
2173 "enumerateQualifiers(): internal error");
|
2174 mike 1.48 }
2175
2176 Array<CIMQualifierDecl> qualifiers;
2177
2178 for (Uint32 i = 0; i < qualifierNames.size(); i++)
2179 {
|
2180 mike 1.51 CIMQualifierDecl qualifier = getQualifier(nameSpace, qualifierNames[i]);
2181 qualifiers.append(qualifier);
|
2182 mike 1.48 }
2183
|
2184 kumpf 1.58 PEG_METHOD_EXIT();
|
2185 mike 1.48 return qualifiers;
2186 }
2187
2188 void CIMRepository::createNameSpace(const String& nameSpace)
2189 {
|
2190 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::createNameSpace");
2191
|
2192 mike 1.48 _nameSpaceManager.createNameSpace(nameSpace);
|
2193 kumpf 1.58
2194 PEG_METHOD_EXIT();
|
2195 mike 1.48 }
2196
2197 Array<String> CIMRepository::enumerateNameSpaces() const
2198 {
|
2199 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::enumerateNameSpaces");
2200
|
2201 mike 1.48 Array<String> nameSpaceNames;
2202 _nameSpaceManager.getNameSpaceNames(nameSpaceNames);
|
2203 kumpf 1.58
2204 PEG_METHOD_EXIT();
|
2205 mike 1.48 return nameSpaceNames;
2206 }
2207
2208 void CIMRepository::deleteNameSpace(const String& nameSpace)
2209 {
|
2210 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::deleteNameSpace");
2211
|
2212 mike 1.48 _nameSpaceManager.deleteNameSpace(nameSpace);
|
2213 kumpf 1.58
2214 PEG_METHOD_EXIT();
|
2215 mike 1.48 }
2216
|
2217 mike 1.51 //----------------------------------------------------------------------
2218 //
|
2219 mike 1.53 // _getInstanceIndexFilePath()
|
2220 mike 1.51 //
2221 // returns the file path of the instance index file.
2222 //
2223 //----------------------------------------------------------------------
2224
|
2225 mike 1.53 String CIMRepository::_getInstanceIndexFilePath(
|
2226 mike 1.48 const String& nameSpace,
2227 const String& className) const
2228 {
|
2229 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_getInstanceIndexFilePath");
2230
|
2231 mike 1.53 String tmp = _nameSpaceManager.getInstanceDataFileBase(
2232 nameSpace, className);
2233
|
2234 mike 1.48 tmp.append(".idx");
|
2235 kumpf 1.58
2236 PEG_METHOD_EXIT();
|
2237 mike 1.48 return tmp;
2238 }
2239
|
2240 mike 1.51 //----------------------------------------------------------------------
2241 //
|
2242 mike 1.53 // _getInstanceDataFilePath()
|
2243 mike 1.51 //
2244 // returns the file path of the instance file.
2245 //
2246 //----------------------------------------------------------------------
2247
|
2248 mike 1.53 String CIMRepository::_getInstanceDataFilePath(
|
2249 mike 1.48 const String& nameSpace,
|
2250 mike 1.51 const String& className) const
|
2251 mike 1.48 {
|
2252 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_getInstanceDataFilePath");
2253
|
2254 mike 1.53 String tmp = _nameSpaceManager.getInstanceDataFileBase(
2255 nameSpace, className);
|
2256 mike 1.51 tmp.append(".instances");
|
2257 kumpf 1.61
|
2258 kumpf 1.58 PEG_METHOD_EXIT();
|
2259 mike 1.48 return tmp;
|
2260 mike 1.51 }
2261
2262 Boolean CIMRepository::_loadInstance(
2263 const String& path,
2264 CIMInstance& object,
2265 Uint32 index,
2266 Uint32 size)
2267 {
|
2268 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::_loadInstance");
2269
|
2270 mike 1.51 //
|
2271 mike 1.53 // Load instance (in XML) from instance file into memory:
|
2272 mike 1.51 //
2273
|
2274 mike 1.53 Array<Sint8> data;
|
2275 mike 1.51
|
2276 mike 1.53 if (!InstanceDataFile::loadInstance(path, index, size, data))
|
2277 kumpf 1.58 {
2278 PEG_METHOD_EXIT();
|
2279 mike 1.51 return false;
|
2280 kumpf 1.58 }
|
2281 mike 1.51
2282 //
|
2283 mike 1.53 // Convert XML into an actual object:
|
2284 mike 1.51 //
2285
|
2286 mike 1.53 XmlParser parser((char*)data.getData());
2287 XmlReader::getObject(parser, object);
|
2288 mike 1.51
|
2289 kumpf 1.58 PEG_METHOD_EXIT();
|
2290 mike 1.51 return true;
|
2291 mike 1.48 }
2292
|
2293 bob 1.49 void CIMRepository::setDeclContext(RepositoryDeclContext *context)
2294 {
|
2295 kumpf 1.58 PEG_METHOD_ENTER(TRC_REPOSITORY, "CIMRepository::setDeclContext");
2296
2297 _context = context;
2298
2299 PEG_METHOD_EXIT();
|
2300 bob 1.49 }
2301
|
2302 mike 1.48 PEGASUS_NAMESPACE_END
|