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