(file) Return to CIMRepository.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

   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 mike  1.51         if (fromProp.getType() == CIMType::REFERENCE)
 646                    {
 647                        for (Uint32 j = 0; j < n; j++)
 648                        {
 649                            CIMConstProperty toProp = assocClass.getProperty(j);
 650            
 651                            if (toProp.getType() == CIMType::REFERENCE &&
 652                                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 mike  1.51                 }
 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 mike  1.51         if (fromProp.getType() == CIMType::REFERENCE)
 770                    {
 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                            if (toProp.getType() == CIMType::REFERENCE &&
 780                                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 mike  1.48     if (pos == PEGASUS_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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2