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

   1 mike  1.1 //BEGIN_LICENSE
   2           //
   3           // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
   4           //
   5           // Permission is hereby granted, free of charge, to any person obtaining a
   6           // copy of this software and associated documentation files (the "Software"),
   7           // to deal in the Software without restriction, including without limitation
   8           // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9           // and/or sell copies of the Software, and to permit persons to whom the
  10           // Software is furnished to do so, subject to the following conditions:
  11           //
  12           // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13           // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14           // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15           // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16           // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17           // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  18           // DEALINGS IN THE SOFTWARE.
  19           //
  20           //END_LICENSE
  21           //BEGIN_HISTORY
  22 mike  1.1 //
  23           // Author:
  24           //
  25 mike  1.2 // $Log: Repository.cpp,v $
  26 mike  1.5 // Revision 1.4  2001/01/31 08:20:51  mike
  27           // Added dispatcher framework.
  28           // Added enumerateInstanceNames.
  29           //
  30 mike  1.4 // Revision 1.3  2001/01/28 04:11:03  mike
  31           // fixed qualifier resolution
  32           //
  33 mike  1.3 // Revision 1.2  2001/01/25 02:12:05  mike
  34           // Added meta-qualifiers to LoadRepository program.
  35           //
  36 mike  1.2 // Revision 1.1.1.1  2001/01/14 19:53:55  mike
  37           // Pegasus import
  38           //
  39 mike  1.1 //
  40           //END_HISTORY
  41           
  42           #include <cctype>
  43           #include <fstream>
  44           #include <Pegasus/Common/Pair.h>
  45           #include <Pegasus/Common/Destroyer.h>
  46           #include <Pegasus/Common/FileSystem.h>
  47           #include <Pegasus/Common/Exception.h>
  48           #include <Pegasus/Common/XmlReader.h>
  49           #include <Pegasus/Common/XmlWriter.h>
  50           #include <Pegasus/Common/DeclContext.h>
  51           #include "Repository.h"
  52           
  53           #define INDENT_XML_FILES
  54           
  55           PEGASUS_NAMESPACE_BEGIN
  56           
  57           ////////////////////////////////////////////////////////////////////////////////
  58           //
  59           // Local functions
  60 mike  1.1 //
  61           ////////////////////////////////////////////////////////////////////////////////
  62           
  63           //------------------------------------------------------------------------------
  64           //
  65           // This routine matches files in the classes directory (given by path)
  66           // that match the second and third arguments, which are eight class names
  67           // or asterisks (which are wild cards). All the files in the ./classes
  68           // directory are of the form <className.superClassName>. For classes
  69           // with no superClass, the superClassName is "#". We consider a couple of
  70           // examples. To find all direct subclasses of "MyClass", we invoke it
  71           // as follows:
  72           //
  73           //	_GlobClassesDir(path, "*", "MyClass");
  74           //
  75           // To find the file which contains the class called "MyClass", we invoke
  76           // it like this.
  77           //
  78           //	_GlobClassesDir(path, "MyClass", "*");
  79           //
  80           // Since base classes are of the form "<ClassName>.#", all baseclasses may
  81 mike  1.1 // be found with:
  82           //
  83           //	_GlobClassesDir(path, "*", "#");
  84           //
  85           // Note that the results (the array of filenames which are returned) must
  86           // be processed further to get the actual class names. The name of the
  87           // class is the filename less the extension. Or this:
  88           //
  89           //	String className = fileName.subString(fileName.find(0, '.'));
  90           //
  91           //------------------------------------------------------------------------------
  92           
  93           Array<String> _GlobClassesDir(
  94               const String& path, 
  95 mike  1.5     const String& className_,
  96               const String& superClassName_)
  97 mike  1.1 {
  98 mike  1.5     String className = className_;
  99               String superClassName = superClassName_;
 100 mike  1.1     Array<String> fileNames;
 101           
 102               if (!FileSystem::getDirectoryContents(path, fileNames))
 103           	throw NoSuchDirectory(path);
 104           
 105               Array<String> result;
 106           
 107               for (Uint32 i = 0; i < fileNames.getSize(); i++)
 108               {
 109           	const String& tmp = fileNames[i];
 110           
 111           	Uint32 dot = tmp.find('.');
 112           
 113           	// Ignore files that do not contain a dot:
 114           
 115           	if (dot == Uint32(-1))
 116           	    continue;
 117           
 118           	String first = tmp.subString(0, dot);
 119           	String second = tmp.subString(dot + 1);
 120           
 121 mike  1.1 	if ((className == "*" || first == className) &&
 122           	    (superClassName == "*" || second == superClassName))
 123           	{
 124           	    result.append(tmp);
 125           	}
 126               }
 127           
 128               return result;
 129           }
 130           
 131           static Boolean _SkipIdentifier(Char16*& p)
 132           {
 133               if (!*p || !(isalpha(*p) || *p == '_'))
 134           	return false;
 135           
 136               for (p++; *p; p++)
 137               {
 138           	if (!(isalnum(*p) || *p == '_'))
 139           	    return true;
 140               }
 141           
 142 mike  1.1     return true;
 143           }
 144           
 145           static void _MakeNameSpacePath(
 146               const String& root,
 147               const String& nameSpace,
 148               String& path)
 149           {
 150               path = root;
 151               path.append('/');
 152           
 153               path.append(nameSpace);
 154           
 155               Char16* p = (Char16*)(path.getData() + root.getLength() + 1);
 156           
 157               while (*p)
 158               {
 159           	// Either we will encounter a slash or an identifier:
 160           
 161           	if (*p == '/')
 162           	{
 163 mike  1.1 	    if (p[1] == '/')
 164           		throw CimException(CimException::INVALID_NAMESPACE);
 165           	    
 166           	    *p++ = '#';
 167           	}
 168           	else if (!_SkipIdentifier(p))
 169           	    throw CimException(CimException::INVALID_NAMESPACE);
 170               }
 171           
 172               // The last element may NOT be a slash (slashes are translated to
 173               // #'s above).
 174           
 175               if (p[-1] == '#')
 176           	throw CimException(CimException::INVALID_NAMESPACE);
 177           }
 178           
 179           void _FindClass(
 180               const String& root, 
 181               const String& nameSpace, 
 182               const String& className,
 183               String& path)
 184 mike  1.1 {
 185               const char CLASSES[] = "/classes/";
 186               _MakeNameSpacePath(root, nameSpace, path);
 187           
 188               if (!FileSystem::isDirectory(path))
 189           	throw CimException(CimException::INVALID_NAMESPACE);
 190           
 191               path.append(CLASSES);
 192           
 193               Array<String> fileNames = _GlobClassesDir(path, className, "*");
 194           
 195               Uint32 size = fileNames.getSize();
 196           
 197               if (size == 0)
 198           	throw CimException(CimException::INVALID_CLASS);
 199           
 200               PEGASUS_ASSERT(size == 1);
 201               path.append(fileNames[0]);
 202           }
 203           
 204           inline Uint32 _min(Uint32 x, Uint32 y)
 205 mike  1.1 {
 206               return x < y ? x : y;
 207           }
 208           
 209           static void _MakeNewClassPath(
 210               const String& root,
 211               const String& nameSpace,
 212               const String& className,
 213               const String& superClassName,
 214               String& path)
 215           {
 216               const char CLASSES[] = "/classes/";
 217               _MakeNameSpacePath(root, nameSpace, path);
 218           
 219               if (!FileSystem::isDirectory(path))
 220           	throw CimException(CimException::INVALID_NAMESPACE);
 221           
 222               path.append(CLASSES);
 223               path.append(className);
 224               path.append('.');
 225           
 226 mike  1.1     if (superClassName.getLength() == 0)
 227           	path.append("#");
 228               else
 229           	path.append(superClassName);
 230           }
 231           
 232           static void _MakeQualfierPath(
 233               const String& root,
 234               const String& nameSpace,
 235               const String& qualifierName,
 236               String& path)
 237           {
 238               const char QUALIFIERS[] = "/qualifiers/";
 239               _MakeNameSpacePath(root, nameSpace, path);
 240           
 241               if (!FileSystem::isDirectory(path))
 242           	throw CimException(CimException::INVALID_NAMESPACE);
 243           
 244               path.append('/');
 245               path.append(QUALIFIERS);
 246               path.append(qualifierName);
 247 mike  1.1 }
 248           
 249           template<class Object>
 250           void _LoadObject(
 251               const String& path,
 252               Object& object)
 253           {
 254 mike  1.5     // Get the real path of the file:
 255 mike  1.1 
 256 mike  1.5     String realPath;
 257 mike  1.1 
 258 mike  1.5     if (!FileSystem::existsIgnoreCase(path, realPath))
 259 mike  1.1 	throw CannotOpenFile(path);
 260           
 261               // Load file into memory:
 262           
 263               Array<Sint8> data;
 264 mike  1.5     FileSystem::loadFileToMemory(data, realPath);
 265 mike  1.1     data.append('\0');
 266           
 267               XmlParser parser((char*)data.getData());
 268           
 269               XmlReader::getObject(parser, object);
 270           }
 271           
 272           template<class Object>
 273           void _SaveObject(const String& path, Object& object)
 274           {
 275               Array<Sint8> out;
 276               object.toXml(out);
 277               out.append('\0');
 278           
 279               Destroyer<char> destroyer(path.allocateCString());
 280           
 281           #ifdef PEGASUS_OS_TYPE_WINDOWS
 282               std::ofstream os(destroyer.getPointer(), std::ios::binary);
 283           #else
 284               std::ofstream os(destroyer.getPointer());
 285           #endif
 286 mike  1.1 
 287               if (!os)
 288           	throw CannotOpenFile(path);
 289           
 290           #ifdef INDENT_XML_FILES
 291               XmlWriter::indentedPrint(os, out.getData(), 2);
 292           #else
 293               os.write((char*)out.getData(), out.getSize());
 294           #endif
 295           }
 296           
 297           static void _AppendClassNames(
 298               const String& path,
 299               const String& className,
 300               const String& superClassName,
 301               Array<String>& classNames)
 302           {
 303               Array<String> allFiles;
 304           
 305               if (!FileSystem::getDirectoryContents(path, allFiles))
 306           	throw NoSuchDirectory(path);
 307 mike  1.1 
 308               // Append all the direct sublclasses of the class to the output argument:
 309           
 310               Array<String> fileNames = 
 311           	_GlobClassesDir(path, className, superClassName);
 312           
 313               for (Uint32 i = 0, n = fileNames.getSize(); i < n; i++)
 314               {
 315           	String& tmp = fileNames[i];
 316           	Uint32 pos = tmp.find('.');
 317           
 318           	PEGASUS_ASSERT(pos != Uint32(-1));
 319           
 320           	if (pos != Uint32(-1))
 321           	    tmp.remove(pos);
 322           
 323           	classNames.append(tmp);
 324               }
 325           }
 326           
 327           typedef Pair<String,String> Node;
 328 mike  1.1 
 329           static void _AppendSubclassesDeepAux(
 330               const Array<Node>& table,
 331               const String& className,
 332               Array<String>& classNames)
 333           {
 334               for (Uint32 i = 0, n = table.getSize(); i < n; i++)
 335               {
 336           	if (className == table[i].second)
 337           	{
 338           	    classNames.append(table[i].first);
 339           	    _AppendSubclassesDeepAux(table, table[i].first, classNames);
 340           	}
 341               }
 342           }
 343           
 344           static void _AppendSubclassesDeep(
 345               const String& path,
 346               const String& className,
 347               Array<String>& classNames)
 348           {
 349 mike  1.1     Array<String> allFiles;
 350           
 351               if (!FileSystem::getDirectoryContents(path, allFiles))
 352           	throw NoSuchDirectory(path);
 353           
 354               Array<Node> table;
 355               table.reserve(allFiles.getSize());
 356           
 357               for (Uint32 i = 0, n = allFiles.getSize(); i < n; i++)
 358               {
 359           	const String& fileName = allFiles[i];
 360           
 361           	Uint32 dot = fileName.find('.');
 362           
 363           	if (dot == Uint32(-1))
 364           	    continue;
 365           
 366           	String first = fileName.subString(0, dot);
 367           	String second = fileName.subString(dot + 1);
 368           
 369           	if (second == "#")
 370 mike  1.1 	    table.append(Node(first, String()));
 371           	else
 372           	    table.append(Node(first, second));
 373               }
 374           
 375               _AppendSubclassesDeepAux(table, className, classNames);
 376           }
 377           
 378           static Boolean _HasSubclasses(
 379               const String& root,
 380               const String& nameSpace,
 381               const String& className)	
 382           {
 383               const char CLASSES[] = "/classes";
 384               String path;
 385               _MakeNameSpacePath(root, nameSpace, path);
 386               path.append(CLASSES);
 387           
 388               Array<String> fileNames = _GlobClassesDir(path, "*", className);
 389           
 390               return fileNames.getSize() != 0;
 391 mike  1.1 }
 392           
 393           ////////////////////////////////////////////////////////////////////////////////
 394           //
 395           // RepositoryDeclContext
 396           //
 397           ////////////////////////////////////////////////////////////////////////////////
 398           
 399           class RepositoryDeclContext : public DeclContext
 400           {
 401           public:
 402           
 403               RepositoryDeclContext(Repository* repository);
 404           
 405               virtual ~RepositoryDeclContext();
 406           
 407               virtual QualifierDecl lookupQualifierDecl(
 408           	const String& nameSpace, 
 409           	const String& qualifierName) const;
 410           
 411               virtual ClassDecl lookupClassDecl(
 412 mike  1.1 	const String& nameSpace, 
 413           	const String& className) const;
 414           
 415           private:
 416           
 417               Repository* _repository;
 418           };
 419           
 420           RepositoryDeclContext::RepositoryDeclContext(Repository* repository) 
 421               : _repository(repository)
 422           {
 423           
 424           }
 425           
 426           RepositoryDeclContext::~RepositoryDeclContext()
 427           {
 428           
 429           }
 430           
 431           QualifierDecl RepositoryDeclContext::lookupQualifierDecl(
 432               const String& nameSpace,
 433 mike  1.1     const String& qualifierName) const
 434           {
 435               // Ignore the exception since this routine is only supposed report
 436               // whether it can be found:
 437           
 438               try
 439               {
 440           	return _repository->getQualifier(nameSpace, qualifierName);
 441               }
 442               catch (Exception&)
 443               {
 444           	return QualifierDecl();
 445               }
 446           }
 447           
 448           ClassDecl RepositoryDeclContext::lookupClassDecl(
 449               const String& nameSpace,
 450               const String& className) const
 451           {
 452               // Ignore the exception since this routine is only supposed report
 453               // whether it can be found:
 454 mike  1.1 
 455               try
 456               {
 457           	return _repository->getClass(nameSpace, className, false, true, true);
 458               }
 459               catch (Exception&)
 460               {
 461           	return ClassDecl();
 462               }
 463           }
 464           
 465           ////////////////////////////////////////////////////////////////////////////////
 466           //
 467           // Repository
 468           //
 469           ////////////////////////////////////////////////////////////////////////////////
 470           
 471           Repository::Repository(const String& path)
 472           {
 473               const char REPOSITORY[] = "/repository";
 474               _root = path;
 475 mike  1.1     _root.append(REPOSITORY);
 476           
 477               if (!FileSystem::isDirectory(_root))
 478               {
 479           	if (!FileSystem::makeDirectory(_root))
 480           	    throw CannotCreateDirectory(_root);
 481               }
 482           
 483               _context = new RepositoryDeclContext(this);
 484           }
 485           
 486           Repository::~Repository()
 487           {
 488           
 489           }
 490           
 491           ClassDecl Repository::getClass(
 492               const String& nameSpace,
 493               const String& className,
 494               Boolean localOnly,
 495               Boolean includeQualifiers,
 496 mike  1.1     Boolean includeClassOrigin,
 497               const Array<String>& propertyList)
 498           {
 499               // Form the path to the class:
 500           
 501               String path;
 502               _FindClass(_root, nameSpace, className, path);
 503           
 504               // Load the class:
 505           
 506               ClassDecl classDecl;
 507               _LoadObject(path, classDecl);
 508           
 509               return ClassDecl(classDecl);
 510           }
 511           
 512           InstanceDecl Repository::getInstance(
 513               const String& nameSpace,
 514               const Reference& instanceName,
 515               Boolean localOnly,
 516               Boolean includeQualifiers,
 517 mike  1.1     Boolean includeClassOrigin,
 518               const Array<String>& propertyList)
 519           {
 520               throw CimException(CimException::NOT_SUPPORTED);
 521               return InstanceDecl();
 522           }
 523           
 524           void Repository::deleteClass(
 525               const String& nameSpace,
 526               const String& className)
 527           {
 528               // Get path of class file:
 529           
 530               String path;
 531               _FindClass(_root, nameSpace, className, path);
 532           
 533               // Disallow if the class has subclasses:
 534           
 535               if (_HasSubclasses(_root, nameSpace, className))
 536           	throw CimException(CimException::CLASS_HAS_CHILDREN);
 537           
 538 mike  1.1     // ATTN-C: check to see if the class has instances:
 539           
 540               // Remove the class:
 541           
 542               if (!FileSystem::removeFile(path))
 543           	throw FailedToRemoveFile(path);
 544           }
 545           
 546           void Repository::deleteInstance(
 547               const String& nameSpace,
 548               const Reference& instanceName) 
 549           { 
 550               throw CimException(CimException::NOT_SUPPORTED);
 551           }
 552           
 553           void Repository::createClass(
 554               const String& nameSpace,
 555               ClassDecl& newClass) 
 556           {
 557               // Form the path to the class:
 558           
 559 mike  1.1     String path;
 560               const String& className = newClass.getClassName();
 561               const String& superClassName = newClass.getSuperClassName();
 562 mike  1.5     _MakeNewClassPath(
 563           	_root, nameSpace, className, superClassName, path);
 564 mike  1.1 
 565 mike  1.5     String realPath;
 566           
 567               if (FileSystem::existsIgnoreCase(path, realPath))
 568 mike  1.1 	throw CimException(CimException::ALREADY_EXISTS);
 569 mike  1.5     else
 570           	realPath = path;
 571 mike  1.1 
 572               // Validate the new class:
 573           
 574               newClass.resolve(_context, nameSpace);
 575           
 576               // Save the class:
 577           
 578 mike  1.5     _SaveObject(realPath, newClass);
 579 mike  1.1 }
 580           
 581           void Repository::createInstance(
 582               const String& nameSpace,
 583               const InstanceDecl& newInstance) 
 584           { 
 585               throw CimException(CimException::NOT_SUPPORTED);
 586           }
 587           
 588           void Repository::modifyClass(
 589               const String& nameSpace,
 590               ClassDecl& modifiedClass) 
 591           {
 592               // ATTN: need lots of semantic checking here:
 593           
 594               // Get the old class:
 595           
 596               ClassDecl oldClass = getClass(
 597           	nameSpace, modifiedClass.getClassName(), false, true, true);
 598           
 599               // Disallow changing the name of the super-class:
 600 mike  1.1 
 601               if (modifiedClass.getSuperClassName() != oldClass.getSuperClassName())
 602           	throw CimException(CimException::INVALID_SUPERCLASS);
 603           
 604               // Delete the old class:
 605           
 606               deleteClass(nameSpace, modifiedClass.getClassName());
 607           
 608               // Create the class again:
 609           
 610               createClass(nameSpace, modifiedClass);
 611           }
 612           
 613           void Repository::modifyInstance(
 614               const String& nameSpace,
 615               const InstanceDecl& modifiedInstance) 
 616           {
 617               throw CimException(CimException::NOT_SUPPORTED);
 618           }
 619           
 620           Array<ClassDecl> Repository::enumerateClasses(
 621 mike  1.1     const String& nameSpace,
 622               const String& className,
 623               Boolean deepInheritance,
 624               Boolean localOnly,
 625               Boolean includeQualifiers,
 626               Boolean includeClassOrigin)
 627           {
 628               Array<String> classNames = 
 629           	enumerateClassNames(nameSpace, className, deepInheritance);
 630           
 631               Array<ClassDecl> result;
 632           
 633               for (Uint32 i = 0; i < classNames.getSize(); i++)
 634               {
 635           	result.append(getClass(nameSpace, classNames[i], localOnly, 
 636           	    includeQualifiers, includeClassOrigin));
 637               }
 638           
 639               return result;
 640           }
 641           
 642 mike  1.1 Array<String> Repository::enumerateClassNames(
 643               const String& nameSpace,
 644               const String& className,
 645               Boolean deepInheritance)
 646           {
 647               // Build the path to the classes directory:
 648           
 649               const char CLASSES[] = "/classes/";
 650               String path;
 651               _MakeNameSpacePath(_root, nameSpace, path);
 652               path.append(CLASSES);
 653           
 654               if (!FileSystem::isDirectory(path))
 655           	throw CimException(CimException::INVALID_NAMESPACE);
 656           
 657               if (deepInheritance)
 658               {
 659           	if (className == String::EMPTY)
 660           	{
 661           	    Array<String> classNames;
 662           	    _AppendSubclassesDeep(path, String(), classNames);
 663 mike  1.1 	    return classNames;
 664           	}
 665           	else
 666           	{
 667           	    Array<String> classNames;
 668           	    _AppendSubclassesDeep(path, className, classNames);
 669           	    return classNames;
 670           	}
 671               }
 672               else
 673               {
 674           	if (className == String::EMPTY)
 675           	{
 676           	    Array<String> classNames;
 677           	    _AppendClassNames(path, "*", "#", classNames);
 678           	    return classNames;
 679           	}
 680           	else
 681           	{
 682           	    Array<String> classNames;
 683           	    _AppendClassNames(path, "*", className, classNames);
 684 mike  1.1 	    return classNames;
 685           	}
 686               }
 687           
 688               // Unreachable:
 689               return Array<String>();
 690           }
 691           
 692           Array<InstanceDecl> Repository::enumerateInstances(
 693               const String& nameSpace,
 694               const String& className,
 695               Boolean deepInheritance,
 696               Boolean localOnly,
 697               Boolean includeQualifiers,
 698               Boolean includeClassOrigin,
 699               const Array<String>& propertyList)
 700           { 
 701               throw CimException(CimException::NOT_SUPPORTED);
 702               return Array<InstanceDecl>();
 703           }
 704           
 705 mike  1.4 Array<Reference> Repository::enumerateInstanceNames(
 706 mike  1.1     const String& nameSpace,
 707               const String& className) 
 708           { 
 709               throw CimException(CimException::NOT_SUPPORTED);
 710 mike  1.4     return Array<Reference>();
 711 mike  1.1 }
 712           
 713           Array<InstanceDecl> Repository::execQuery(
 714               const String& queryLanguage,
 715               const String& query) 
 716           { 
 717               throw CimException(CimException::NOT_SUPPORTED);
 718               return Array<InstanceDecl>();
 719           }
 720           
 721           Array<InstanceDecl> Repository::associators(
 722               const String& nameSpace,
 723               const Reference& objectName,
 724               const String& assocClass,
 725               const String& resultClass,
 726               const String& role,
 727               const String& resultRole,
 728               Boolean includeQualifiers,
 729               Boolean includeClassOrigin,
 730               const Array<String>& propertyList)
 731           {
 732 mike  1.1     throw CimException(CimException::NOT_SUPPORTED);
 733               return Array<InstanceDecl>();
 734           }
 735           
 736           Array<Reference> Repository::associatorNames(
 737               const String& nameSpace,
 738               const Reference& objectName,
 739               const String& assocClass,
 740               const String& resultClass,
 741               const String& role,
 742               const String& resultRole)
 743           { 
 744               throw CimException(CimException::NOT_SUPPORTED);
 745               return Array<Reference>();
 746           }
 747           
 748           Array<InstanceDecl> Repository::references(
 749               const String& nameSpace,
 750               const Reference& objectName,
 751               const String& resultClass,
 752               const String& role,
 753 mike  1.1     Boolean includeQualifiers,
 754               Boolean includeClassOrigin,
 755               const Array<String>& propertyList)
 756           {
 757               throw CimException(CimException::NOT_SUPPORTED);
 758               return Array<InstanceDecl>();
 759           }
 760           
 761           Array<Reference> Repository::referenceNames(
 762               const String& nameSpace,
 763               const Reference& objectName,
 764               const String& resultClass,
 765               const String& role)
 766           { 
 767               throw CimException(CimException::NOT_SUPPORTED);
 768               return Array<Reference>();
 769           }
 770           
 771           Value Repository::getProperty(
 772               const String& nameSpace,
 773               const Reference& instanceName,
 774 mike  1.1     const String& propertyName) 
 775           { 
 776               throw CimException(CimException::NOT_SUPPORTED);
 777               return Value();
 778           }
 779           
 780           void Repository::setProperty(
 781               const String& nameSpace,
 782               const Reference& instanceName,
 783               const String& propertyName,
 784               const Value& newValue)
 785           { 
 786               throw CimException(CimException::NOT_SUPPORTED);
 787           }
 788           
 789           QualifierDecl Repository::getQualifier(
 790               const String& nameSpace,
 791               const String& qualifierName) 
 792           {
 793               // Form the path of the qualifier file:
 794           
 795 mike  1.1     String path;
 796               _MakeQualfierPath(_root, nameSpace, qualifierName, path);
 797           
 798               // If it does not exist:
 799           
 800 mike  1.5     String realPath;
 801           
 802               if (!FileSystem::existsIgnoreCase(path, realPath))
 803 mike  1.1 	throw CimException(CimException::NOT_FOUND);
 804           
 805               // Load the qualifier:
 806           
 807               QualifierDecl qualifierDecl;
 808 mike  1.5     _LoadObject(realPath, qualifierDecl);
 809           
 810               // Return the qualifier:
 811 mike  1.1 
 812               return QualifierDecl(qualifierDecl);
 813           }
 814           
 815           void Repository::setQualifier(
 816               const String& nameSpace,
 817               const QualifierDecl& qualifierDecl) 
 818           {
 819               // Form the path of the qualifier:
 820           
 821               String path;
 822               _MakeQualfierPath(_root, nameSpace, qualifierDecl.getName(), path);
 823           
 824               // If the qualifier already exists, delete it:
 825           
 826 mike  1.5     String realPath;
 827           
 828               if (FileSystem::existsIgnoreCase(path, realPath))
 829 mike  1.1     {
 830 mike  1.5 	if (!FileSystem::removeFile(realPath))
 831 mike  1.1 	    throw FailedToRemoveDirectory(path);
 832               }
 833 mike  1.5     else
 834           	realPath = path;
 835 mike  1.1 
 836               // Write the qualifier to file:
 837           
 838 mike  1.5     _SaveObject(realPath, qualifierDecl);
 839 mike  1.1 }
 840           
 841           void Repository::deleteQualifier(
 842               const String& nameSpace,
 843               const String& qualifierName) 
 844           {
 845               String path;
 846               _MakeQualfierPath(_root, nameSpace, qualifierName, path);
 847           
 848 mike  1.5     String realPath;
 849           
 850               if (!FileSystem::existsIgnoreCase(path, realPath))
 851 mike  1.1 	throw CimException(CimException::NOT_FOUND);
 852           
 853 mike  1.5     if (!FileSystem::removeFile(realPath))
 854 mike  1.1 	throw FailedToRemoveFile(path);
 855           }
 856           
 857           Array<QualifierDecl> Repository::enumerateQualifiers(
 858               const String& nameSpace)
 859           {
 860               // Build the path to the qualifiers directory:
 861           
 862               const char QUALIFIERS[] = "/qualifiers/";
 863               String path;
 864               _MakeNameSpacePath(_root, nameSpace, path);
 865               path.append(QUALIFIERS);
 866           
 867               if (!FileSystem::isDirectory(path))
 868           	throw CimException(CimException::INVALID_NAMESPACE);
 869           
 870               // Get the names of the qualifiers:
 871           
 872               Array<String> qualifierNames;
 873           
 874               if (!FileSystem::getDirectoryContents(path, qualifierNames))
 875 mike  1.1 	throw NoSuchDirectory(path);
 876           
 877               // Load each qualifier into the result array:
 878           
 879               Array<QualifierDecl> result;
 880           
 881               for (Uint32 i = 0, n = qualifierNames.getSize(); i < n; i++)
 882               {
 883           	QualifierDecl tmp = getQualifier(nameSpace, qualifierNames[i]);
 884           	result.append(tmp);
 885               }
 886           
 887               return result;
 888           }
 889           
 890           Value Repository::invokeMethod(
 891               const String& nameSpace,
 892               const Reference& instanceName,
 893               const String& methodName,
 894               const Array<Value>& inParameters,
 895               Array<Value>& outParameters) 
 896 mike  1.1 {
 897               throw CimException(CimException::NOT_SUPPORTED);
 898               return Value();
 899           }
 900           
 901           ////////////////////////////////////////////////////////////////////////////////
 902           //
 903           // New methods
 904           //
 905           ////////////////////////////////////////////////////////////////////////////////
 906           
 907           void Repository::createNameSpace(const String& nameSpace)
 908           {
 909               String path;
 910               _MakeNameSpacePath(_root, nameSpace, path);
 911           
 912               if (FileSystem::exists(path))
 913           	throw AlreadyExists(nameSpace);
 914           
 915               if (!FileSystem::makeDirectory(path))
 916           	throw CannotCreateDirectory(path);
 917 mike  1.1 
 918               // Create "./qualifiers" directory:
 919           
 920               String qualifiersDir = path;
 921               qualifiersDir.append("/qualifiers");
 922           
 923               if (!FileSystem::makeDirectory(qualifiersDir))
 924           	throw CannotCreateDirectory(qualifiersDir);
 925           
 926               // Create "./classes" directory:
 927           
 928               String classesDir = path;
 929               classesDir.append("/classes");
 930           
 931               if (!FileSystem::makeDirectory(classesDir))
 932           	throw CannotCreateDirectory(classesDir);
 933           
 934               // Create "./instances" directory:
 935           
 936               String instancesDir = path;
 937               instancesDir.append("/instances");
 938 mike  1.1 
 939               if (!FileSystem::makeDirectory(instancesDir))
 940           	throw CannotCreateDirectory(instancesDir);
 941           }
 942           
 943           Array<String> Repository::enumerateNameSpaces() const
 944           {
 945               Array<String> result;
 946           
 947               if (!FileSystem::getDirectoryContents(_root, result))
 948           	throw NoSuchDirectory(_root);
 949           
 950               for (Uint32 i = 0, n = result.getSize(); i < n; i++)
 951               {
 952           	const String& tmp = result[i];
 953           
 954           	for (Char16* p = (Char16*)tmp.getData(); *p; p++)
 955           	{
 956           	    if (*p == '#')
 957           		*p = '/';
 958           	}
 959 mike  1.1     }
 960           
 961               return result;
 962 mike  1.3 }
 963           
 964           // Recall flavor defaults: TOSUBCLASS | OVERRIDABLE
 965           
 966           void Repository::createMetaQualifiers(const String& nameSpace)
 967           {
 968               // Qualifier CimType : string = null, 
 969               //     Scope(property, parameter)
 970           
 971               setQualifier(nameSpace, QualifierDecl("cimtype", String(),
 972           	Scope::PROPERTY | Scope::REFERENCE | Scope::PARAMETER));
 973           
 974               // Qualifier id : sint32 = null, 
 975               //     Scope(any), 
 976               //     Flavor(toinstance)
 977           
 978               setQualifier(nameSpace, QualifierDecl("id", Sint32(0),
 979           	Scope::ANY,
 980           	Flavor::TOINSTANCE));
 981           
 982               // Qualifier OctetString : boolean = false, Scope(property)
 983 mike  1.3 
 984               setQualifier(nameSpace, QualifierDecl("octetstring", false,
 985           	Scope::PROPERTY));
 986               
 987               // Qualifier Abstract : boolean = false, 
 988               //     Scope(class, association, indication),
 989               //     Flavor(disableoverride, restricted);
 990           
 991               setQualifier(nameSpace, QualifierDecl("abstract", false, 
 992           	Scope::CLASS | Scope::ASSOCIATION | Scope::INDICATION,
 993           	Flavor::NONE));
 994           
 995               // Qualifier Aggregate : boolean = false, 
 996               //    Scope(reference),
 997               //    Flavor(disableoverride, tosubclass);
 998           
 999               setQualifier(nameSpace, QualifierDecl("aggregate", false, 
1000           	Scope::REFERENCE, Flavor::TOSUBCLASS));
1001           
1002               // Qualifier Aggregation : boolean = false, 
1003               //     Scope(association),
1004 mike  1.3     //     Flavor(disableoverride, tosubclass);
1005           
1006               setQualifier(nameSpace, QualifierDecl("aggregation", false, 
1007           	Scope::ASSOCIATION, Flavor::TOSUBCLASS));
1008           
1009               // Qualifier Alias : string = null, 
1010               //     Scope(property, reference, method), 
1011               //     Flavor(translatable);
1012           
1013               setQualifier(nameSpace, QualifierDecl("alias", String(),
1014           	Scope::PROPERTY | Scope::REFERENCE | Scope::METHOD,
1015           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1016           
1017               // Qualifier ArrayType : string = "Bag", 
1018               //     Scope(property, parameter);
1019           
1020               setQualifier(nameSpace, QualifierDecl("arraytype", "Bag",
1021           	Scope::PROPERTY | Scope::PARAMETER));
1022           
1023               // Qualifier Association : boolean = false, 
1024               //     Scope(class, association),
1025 mike  1.3     //     Flavor(disableoverride);
1026           
1027               setQualifier(nameSpace, QualifierDecl("association", false,
1028           	Scope::CLASS | Scope::ASSOCIATION,
1029           	Flavor::TOSUBCLASS));
1030           
1031               // Qualifier BitMap : string[], 
1032               //     Scope(property, method, parameter);
1033           
1034               setQualifier(nameSpace, QualifierDecl("bitmap", Array<String>(),
1035           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1036           
1037               // Qualifier BitValues : string[], 
1038               //     Scope(property, method, parameter),
1039               //     Flavor(Translatable);
1040           
1041               setQualifier(nameSpace, QualifierDecl("bitvalues", Array<String>(),
1042           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER,
1043           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1044           
1045               // Qualifier Counter : boolean = false, 
1046 mike  1.3     //     Scope(property, method, parameter);
1047           
1048               setQualifier(nameSpace, QualifierDecl("counter", false,
1049           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1050           
1051               // Qualifier Delete : boolean = false, 
1052               //     Scope(association, reference);
1053           
1054               setQualifier(nameSpace, QualifierDecl("delete", false,
1055           	Scope::ASSOCIATION | Scope::REFERENCE));
1056           
1057               // Qualifier Description : string = null, 
1058               //     Scope(any), 
1059               //     Flavor(translatable);
1060           
1061               setQualifier(nameSpace, QualifierDecl("description", String(),
1062           	Scope::ANY, 
1063           	Flavor::TRANSLATABLE));
1064           
1065               // Qualifier DisplayName : string = null, 
1066               //     Scope(any), 
1067 mike  1.3     //     Flavor(translatable);
1068           
1069               setQualifier(nameSpace, QualifierDecl("displayname", String(),
1070           	Scope::ANY,
1071           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1072           
1073               // Qualifier Expensive : boolean = false,
1074               //     Scope(property, reference, method, class, association);
1075           
1076               setQualifier(nameSpace, QualifierDecl("expensive", false,
1077           	Scope::PROPERTY | Scope::REFERENCE | Scope::METHOD | Scope::CLASS |
1078           	Scope::ASSOCIATION));
1079           
1080               // Qualifier Gauge : boolean = false, 
1081               //     Scope(property, method, parameter);
1082           
1083               setQualifier(nameSpace, QualifierDecl("gauge", false,
1084           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1085           
1086               // Qualifier Ifdeleted : boolean = false, 
1087               //     Scope(association, reference);
1088 mike  1.3 
1089               setQualifier(nameSpace, QualifierDecl("ifdeleted", false,
1090           	Scope::ASSOCIATION | Scope::REFERENCE));
1091           
1092               // Qualifier In : boolean = true, 
1093               //     Scope(parameter), 
1094               //     Flavor(disableoverride);
1095           
1096               setQualifier(nameSpace, QualifierDecl("in", true,
1097           	Scope::PARAMETER,
1098           	Flavor::TOSUBCLASS));
1099           
1100               // Qualifier Indication : boolean = false, 
1101               //     Scope(class, indication),
1102               //     Flavor(disableoverride);
1103           
1104               setQualifier(nameSpace, QualifierDecl("indication", false,
1105           	Scope::CLASS | Scope::INDICATION,
1106           	Flavor::TOSUBCLASS));
1107           
1108               // Qualifier Invisible : boolean = false,
1109 mike  1.3     //     Scope(reference, association, class, property, method);
1110           
1111               setQualifier(nameSpace, QualifierDecl("invisible", false,
1112           	Scope::REFERENCE | Scope::ASSOCIATION | Scope::CLASS | Scope::PROPERTY |
1113           	Scope::METHOD));
1114           
1115               // Qualifier Key : boolean = false, 
1116               //     Scope(property, reference),
1117               //     Flavor(disableoverride);
1118           
1119               setQualifier(nameSpace, QualifierDecl("key", false,
1120           	Scope::PROPERTY | Scope::REFERENCE,
1121           	Flavor::TOSUBCLASS));
1122           
1123               // Qualifier Large : boolean = false, 
1124               //     Scope(property, class);
1125           
1126               setQualifier(nameSpace, QualifierDecl("large", false,
1127           	Scope::PROPERTY | Scope::CLASS));
1128           
1129               // Qualifier MappingStrings : string[],
1130 mike  1.3     //     Scope(class, property, association, indication, reference);
1131           
1132               setQualifier(nameSpace, QualifierDecl("mappingstrings", Array<String>(),
1133           	Scope::CLASS | Scope::PROPERTY | Scope::ASSOCIATION | 
1134           	Scope::INDICATION | Scope::REFERENCE));
1135           
1136               // Qualifier Max : uint32 = null, Scope(reference);
1137           
1138               setQualifier(nameSpace, QualifierDecl("max", Sint32(0),
1139           	Scope::PROPERTY | Scope::REFERENCE));
1140           
1141               // Qualifier MaxLen : uint32 = null, 
1142               //     Scope(property, method, parameter);
1143           
1144           #if 0
1145               setQualifier(nameSpace, QualifierDecl("maxlen", Uint32(0),
1146           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1147           #else
1148               setQualifier(nameSpace, QualifierDecl("maxlen", Sint32(0),
1149           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1150           #endif
1151 mike  1.3 
1152               // Qualifier MaxValue : sint64 = null, 
1153               //     Scope(property, method, parameter);
1154               // ATTN: XML schema requires sint32!
1155           
1156               setQualifier(nameSpace, QualifierDecl("maxvalue", Sint32(0),
1157           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1158               
1159               // Qualifier Min : sint32 = null, Scope(reference);
1160           
1161               setQualifier(nameSpace, QualifierDecl("min", Sint32(0),
1162           	Scope::REFERENCE));
1163           
1164               // Qualifier MinValue : sint64 = null, 
1165               //     Scope(property, method, parameter);
1166               // ATTN: Type expected by XML spec is sint32!
1167           
1168               setQualifier(nameSpace, QualifierDecl("minvalue", Sint32(0),
1169           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1170           
1171               // Qualifier ModelCorrespondence : string[], 
1172 mike  1.3     //     Scope(property);
1173           
1174               setQualifier(nameSpace, QualifierDecl("modelcorrespondence", 
1175           	Array<String>(),
1176           	Scope::PROPERTY));
1177           
1178               // Qualifier NonLocal : string = null, 
1179               //     Scope(reference);
1180           
1181               setQualifier(nameSpace, QualifierDecl("nonlocal", String(),
1182           	Scope::REFERENCE));
1183           
1184               // Qualifier NullValue : string = null, 
1185               //     Scope(property),
1186               //     Flavor(tosubclass, disableoverride);
1187           
1188               setQualifier(nameSpace, QualifierDecl("nullvalue", String(),
1189           	Scope::PROPERTY,
1190           	Flavor::TOSUBCLASS));
1191           
1192               // Qualifier Out : boolean = false, 
1193 mike  1.3     //     Scope(parameter), 
1194               //     Flavor(disableoverride);
1195           
1196               setQualifier(nameSpace, QualifierDecl("out", false,
1197           	Scope::PARAMETER,
1198           	Flavor::TOSUBCLASS));
1199           
1200               // Qualifier Override : string = null, 
1201               //     Scope(property, method, reference),
1202               //     Flavor(disableoverride);
1203           
1204               setQualifier(nameSpace, QualifierDecl("override", String(),
1205           	Scope::PROPERTY | Scope::METHOD | Scope::REFERENCE,
1206           	Flavor::TOSUBCLASS));
1207           
1208               // Qualifier Propagated : string = null, 
1209               //     Scope(property, reference),
1210               //     Flavor(disableoverride);
1211           
1212               setQualifier(nameSpace, QualifierDecl("propagated", String(),
1213           	Scope::PROPERTY | Scope::REFERENCE,
1214 mike  1.3 	Flavor::TOSUBCLASS));
1215           
1216               // Qualifier Provider : string = null, 
1217               //     Scope(any);
1218           
1219               setQualifier(nameSpace, QualifierDecl("provider", String(),
1220           	Scope::ANY));
1221           
1222               // Qualifier Read : boolean = true, Scope(property);
1223           
1224               setQualifier(nameSpace, QualifierDecl("read", true,
1225           	Scope::PROPERTY));
1226           
1227               // Qualifier Required : boolean = false, 
1228               //     Scope(property);
1229           
1230               setQualifier(nameSpace, QualifierDecl("required", false,
1231           	Scope::PROPERTY));
1232           
1233               // Qualifier Revision : string = null,
1234               //     Scope(schema, class, association, indication),
1235 mike  1.3     //     Flavor(translatable);
1236               // ATTN: No such scope as Scope::SCHEMA
1237           
1238               setQualifier(nameSpace, QualifierDecl("revision", String(),
1239           	Scope::CLASS | Scope::ASSOCIATION | Scope::INDICATION,
1240           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1241           
1242               // Qualifier Schema : string = null, 
1243               //     Scope(property, method),
1244               //     Flavor(disableoverride, translatable);
1245           
1246               setQualifier(nameSpace, QualifierDecl("schema", String(),
1247           	Scope::PROPERTY | Scope::METHOD,
1248           	Flavor::TOSUBCLASS | Flavor::TRANSLATABLE));
1249           
1250               // Qualifier Source : string = null, 
1251               //     Scope(class, association, indication);
1252           
1253               setQualifier(nameSpace, QualifierDecl("source", String(),
1254           	Scope::CLASS | Scope::ASSOCIATION | Scope::INDICATION));
1255           
1256 mike  1.3     // Qualifier SourceType : string = null,
1257               //     Scope(class, association, indication,reference);
1258           
1259               setQualifier(nameSpace, QualifierDecl("sourcetype", String(),
1260           	Scope::CLASS | Scope::ASSOCIATION | Scope:: INDICATION |
1261           	Scope::REFERENCE));
1262               
1263               // Qualifier Static : boolean = false,
1264               //     Scope(property, method), Flavor(disableoverride);
1265           
1266               setQualifier(nameSpace, QualifierDecl("static", false,
1267           	Scope::PROPERTY | Scope::METHOD,
1268           	Flavor::TOSUBCLASS));
1269           
1270               // Qualifier Syntax : string = null,
1271               //     Scope(property, reference, method, parameter);
1272           
1273               setQualifier(nameSpace, QualifierDecl("syntax", String(),
1274           	Scope::PROPERTY | Scope::REFERENCE | Scope::METHOD | Scope::PARAMETER));
1275           
1276               // Qualifier SyntaxType : string = null,
1277 mike  1.3     //     Scope(property, reference, method, parameter);
1278           
1279               setQualifier(nameSpace, QualifierDecl("syntaxtype", String(),
1280           	Scope::PROPERTY | Scope::REFERENCE | Scope::METHOD | Scope::PARAMETER));
1281           
1282               // Qualifier Terminal : boolean = false, 
1283               //     Scope(class);
1284           
1285               setQualifier(nameSpace, QualifierDecl("terminal", false,
1286           	Scope::CLASS));
1287           
1288               // Qualifier TriggerType : string = null,
1289               //     Scope(class, property, reference, method, association, indication);
1290           
1291               setQualifier(nameSpace, QualifierDecl("triggertype", String(),
1292           	Scope::CLASS | Scope::PROPERTY | Scope::REFERENCE | Scope::METHOD |
1293           	Scope::ASSOCIATION | Scope::INDICATION));
1294           
1295               // Qualifier Units : string = null, 
1296               //     Scope(property, method, parameter),
1297               //     Flavor(translatable);
1298 mike  1.3 
1299               setQualifier(nameSpace, QualifierDecl("units", String(),
1300           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER,
1301           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1302           
1303               // Qualifier UnknownValues : string[], 
1304               //     Scope(property), 
1305               //     Flavor(disableoverride, tosubclass);
1306           
1307               setQualifier(nameSpace, QualifierDecl("unknownvalues", Array<String>(),
1308           	Scope::PROPERTY,
1309           	Flavor::TOSUBCLASS));
1310           
1311               // Qualifier UnsupportedValues : string[], 
1312               //     Scope(property),
1313               //     Flavor(disableoverride, tosubclass);
1314           
1315               setQualifier(nameSpace, QualifierDecl("unsupportedvalues", Array<String>(),
1316           	Scope::PROPERTY,
1317           	Flavor::TOSUBCLASS));
1318           
1319 mike  1.3     // Qualifier ValueMap : string[], 
1320               //     Scope(property, method, parameter);
1321           
1322               setQualifier(nameSpace, QualifierDecl("valuemap", Array<String>(),
1323           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER));
1324           
1325               // Qualifier Values : string[], 
1326               //     Scope(property, method, parameter),
1327               //     Flavor(translatable);
1328           
1329               setQualifier(nameSpace, QualifierDecl("values", Array<String>(),
1330           	Scope::PROPERTY | Scope::METHOD | Scope::PARAMETER,
1331           	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1332           
1333               // Qualifier Version : string = null,
1334               //     Scope(schema, class, association, indication), 
1335               //     Flavor(translatable);
1336               // ATTN: No such scope as Scope::SCHEMA
1337           
1338               setQualifier(nameSpace, QualifierDecl("version", String(),
1339           	Scope::CLASS | Scope::ASSOCIATION | Scope::INDICATION,
1340 mike  1.3 	Flavor::DEFAULTS | Flavor::TRANSLATABLE));
1341           
1342               // Qualifier Weak : boolean = false, 
1343               //     Scope(reference),
1344               //     Flavor(disableoverride, tosubclass);
1345           
1346               setQualifier(nameSpace, QualifierDecl("weak", false,
1347           	Scope::REFERENCE,
1348           	Flavor::TOSUBCLASS));
1349           
1350               // Qualifier Write : boolean = false, 
1351               //     Scope(property);
1352           
1353               setQualifier(nameSpace, QualifierDecl("write", false,
1354           	Scope::PROPERTY));
1355 mike  1.1 }
1356           
1357           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2