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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2