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 // $Log$
26 //
27 //END_HISTORY
28
29 #include <cctype>
30 #include <fstream>
31 #include <Pegasus/Common/Pair.h>
32 #include <Pegasus/Common/Destroyer.h>
33 #include <Pegasus/Common/FileSystem.h>
34 #include <Pegasus/Common/Exception.h>
35 #include <Pegasus/Common/XmlReader.h>
36 #include <Pegasus/Common/XmlWriter.h>
37 #include <Pegasus/Common/DeclContext.h>
38 #include "Repository.h"
39
40 #define INDENT_XML_FILES
41
42 PEGASUS_NAMESPACE_BEGIN
43 mike 1.1
44 ////////////////////////////////////////////////////////////////////////////////
45 //
46 // Local functions
47 //
48 ////////////////////////////////////////////////////////////////////////////////
49
50 //------------------------------------------------------------------------------
51 //
52 // This routine matches files in the classes directory (given by path)
53 // that match the second and third arguments, which are eight class names
54 // or asterisks (which are wild cards). All the files in the ./classes
55 // directory are of the form <className.superClassName>. For classes
56 // with no superClass, the superClassName is "#". We consider a couple of
57 // examples. To find all direct subclasses of "MyClass", we invoke it
58 // as follows:
59 //
60 // _GlobClassesDir(path, "*", "MyClass");
61 //
62 // To find the file which contains the class called "MyClass", we invoke
63 // it like this.
64 mike 1.1 //
65 // _GlobClassesDir(path, "MyClass", "*");
66 //
67 // Since base classes are of the form "<ClassName>.#", all baseclasses may
68 // be found with:
69 //
70 // _GlobClassesDir(path, "*", "#");
71 //
72 // Note that the results (the array of filenames which are returned) must
73 // be processed further to get the actual class names. The name of the
74 // class is the filename less the extension. Or this:
75 //
76 // String className = fileName.subString(fileName.find(0, '.'));
77 //
78 //------------------------------------------------------------------------------
79
80 Array<String> _GlobClassesDir(
81 const String& path,
82 const String& className,
83 const String& superClassName)
84 {
85 mike 1.1 Array<String> fileNames;
86
87 if (!FileSystem::getDirectoryContents(path, fileNames))
88 throw NoSuchDirectory(path);
89
90 Array<String> result;
91
92 for (Uint32 i = 0; i < fileNames.getSize(); i++)
93 {
94 const String& tmp = fileNames[i];
95
96 Uint32 dot = tmp.find('.');
97
98 // Ignore files that do not contain a dot:
99
100 if (dot == Uint32(-1))
101 continue;
102
103 String first = tmp.subString(0, dot);
104 String second = tmp.subString(dot + 1);
105
106 mike 1.1 if ((className == "*" || first == className) &&
107 (superClassName == "*" || second == superClassName))
108 {
109 result.append(tmp);
110 }
111 }
112
113 return result;
114 }
115
116 static Boolean _SkipIdentifier(Char16*& p)
117 {
118 if (!*p || !(isalpha(*p) || *p == '_'))
119 return false;
120
121 for (p++; *p; p++)
122 {
123 if (!(isalnum(*p) || *p == '_'))
124 return true;
125 }
126
127 mike 1.1 return true;
128 }
129
130 static void _MakeNameSpacePath(
131 const String& root,
132 const String& nameSpace,
133 String& path)
134 {
135 path = root;
136 path.append('/');
137
138 path.append(nameSpace);
139
140 Char16* p = (Char16*)(path.getData() + root.getLength() + 1);
141
142 while (*p)
143 {
144 // Either we will encounter a slash or an identifier:
145
146 if (*p == '/')
147 {
148 mike 1.1 if (p[1] == '/')
149 throw CimException(CimException::INVALID_NAMESPACE);
150
151 *p++ = '#';
152 }
153 else if (!_SkipIdentifier(p))
154 throw CimException(CimException::INVALID_NAMESPACE);
155 }
156
157 // The last element may NOT be a slash (slashes are translated to
158 // #'s above).
159
160 if (p[-1] == '#')
161 throw CimException(CimException::INVALID_NAMESPACE);
162 }
163
164 void _FindClass(
165 const String& root,
166 const String& nameSpace,
167 const String& className,
168 String& path)
169 mike 1.1 {
170 const char CLASSES[] = "/classes/";
171 _MakeNameSpacePath(root, nameSpace, path);
172
173 if (!FileSystem::isDirectory(path))
174 throw CimException(CimException::INVALID_NAMESPACE);
175
176 path.append(CLASSES);
177
178 Array<String> fileNames = _GlobClassesDir(path, className, "*");
179
180 Uint32 size = fileNames.getSize();
181
182 if (size == 0)
183 throw CimException(CimException::INVALID_CLASS);
184
185 PEGASUS_ASSERT(size == 1);
186 path.append(fileNames[0]);
187 }
188
189 inline Uint32 _min(Uint32 x, Uint32 y)
190 mike 1.1 {
191 return x < y ? x : y;
192 }
193
194 static void _MakeNewClassPath(
195 const String& root,
196 const String& nameSpace,
197 const String& className,
198 const String& superClassName,
199 String& path)
200 {
201 const char CLASSES[] = "/classes/";
202 _MakeNameSpacePath(root, nameSpace, path);
203
204 if (!FileSystem::isDirectory(path))
205 throw CimException(CimException::INVALID_NAMESPACE);
206
207 path.append(CLASSES);
208 path.append(className);
209 path.append('.');
210
211 mike 1.1 if (superClassName.getLength() == 0)
212 path.append("#");
213 else
214 path.append(superClassName);
215 }
216
217 static void _MakeQualfierPath(
218 const String& root,
219 const String& nameSpace,
220 const String& qualifierName,
221 String& path)
222 {
223 const char QUALIFIERS[] = "/qualifiers/";
224 _MakeNameSpacePath(root, nameSpace, path);
225
226 if (!FileSystem::isDirectory(path))
227 throw CimException(CimException::INVALID_NAMESPACE);
228
229 path.append('/');
230 path.append(QUALIFIERS);
231 path.append(qualifierName);
232 mike 1.1 }
233
234 template<class Object>
235 void _LoadObject(
236 const String& path,
237 Object& object)
238 {
239 // Open the file:
240
241 Destroyer<char> destroyer(path.allocateCString());
242 std::ifstream is(destroyer.getPointer());
243
244 if (!is)
245 throw CannotOpenFile(path);
246
247 // Load file into memory:
248
249 Array<Sint8> data;
250 FileSystem::loadFileToMemory(data, path);
251 data.append('\0');
252
253 mike 1.1 XmlParser parser((char*)data.getData());
254
255 XmlReader::getObject(parser, object);
256 }
257
258 template<class Object>
259 void _SaveObject(const String& path, Object& object)
260 {
261 Array<Sint8> out;
262 object.toXml(out);
263 out.append('\0');
264
265 Destroyer<char> destroyer(path.allocateCString());
266
267 #ifdef PEGASUS_OS_TYPE_WINDOWS
268 std::ofstream os(destroyer.getPointer(), std::ios::binary);
269 #else
270 std::ofstream os(destroyer.getPointer());
271 #endif
272
273 if (!os)
274 mike 1.1 throw CannotOpenFile(path);
275
276 #ifdef INDENT_XML_FILES
277 XmlWriter::indentedPrint(os, out.getData(), 2);
278 #else
279 os.write((char*)out.getData(), out.getSize());
280 #endif
281 }
282
283 static void _AppendClassNames(
284 const String& path,
285 const String& className,
286 const String& superClassName,
287 Array<String>& classNames)
288 {
289 Array<String> allFiles;
290
291 if (!FileSystem::getDirectoryContents(path, allFiles))
292 throw NoSuchDirectory(path);
293
294 // Append all the direct sublclasses of the class to the output argument:
295 mike 1.1
296 Array<String> fileNames =
297 _GlobClassesDir(path, className, superClassName);
298
299 for (Uint32 i = 0, n = fileNames.getSize(); i < n; i++)
300 {
301 String& tmp = fileNames[i];
302 Uint32 pos = tmp.find('.');
303
304 PEGASUS_ASSERT(pos != Uint32(-1));
305
306 if (pos != Uint32(-1))
307 tmp.remove(pos);
308
309 classNames.append(tmp);
310 }
311 }
312
313 typedef Pair<String,String> Node;
314
315 static void _AppendSubclassesDeepAux(
316 mike 1.1 const Array<Node>& table,
317 const String& className,
318 Array<String>& classNames)
319 {
320 for (Uint32 i = 0, n = table.getSize(); i < n; i++)
321 {
322 if (className == table[i].second)
323 {
324 classNames.append(table[i].first);
325 _AppendSubclassesDeepAux(table, table[i].first, classNames);
326 }
327 }
328 }
329
330 static void _AppendSubclassesDeep(
331 const String& path,
332 const String& className,
333 Array<String>& classNames)
334 {
335 Array<String> allFiles;
336
337 mike 1.1 if (!FileSystem::getDirectoryContents(path, allFiles))
338 throw NoSuchDirectory(path);
339
340 Array<Node> table;
341 table.reserve(allFiles.getSize());
342
343 for (Uint32 i = 0, n = allFiles.getSize(); i < n; i++)
344 {
345 const String& fileName = allFiles[i];
346
347 Uint32 dot = fileName.find('.');
348
349 if (dot == Uint32(-1))
350 continue;
351
352 String first = fileName.subString(0, dot);
353 String second = fileName.subString(dot + 1);
354
355 if (second == "#")
356 table.append(Node(first, String()));
357 else
358 mike 1.1 table.append(Node(first, second));
359 }
360
361 _AppendSubclassesDeepAux(table, className, classNames);
362 }
363
364 static Boolean _HasSubclasses(
365 const String& root,
366 const String& nameSpace,
367 const String& className)
368 {
369 const char CLASSES[] = "/classes";
370 String path;
371 _MakeNameSpacePath(root, nameSpace, path);
372 path.append(CLASSES);
373
374 Array<String> fileNames = _GlobClassesDir(path, "*", className);
375
376 return fileNames.getSize() != 0;
377 }
378
379 mike 1.1 ////////////////////////////////////////////////////////////////////////////////
380 //
381 // RepositoryDeclContext
382 //
383 ////////////////////////////////////////////////////////////////////////////////
384
385 class RepositoryDeclContext : public DeclContext
386 {
387 public:
388
389 RepositoryDeclContext(Repository* repository);
390
391 virtual ~RepositoryDeclContext();
392
393 virtual QualifierDecl lookupQualifierDecl(
394 const String& nameSpace,
395 const String& qualifierName) const;
396
397 virtual ClassDecl lookupClassDecl(
398 const String& nameSpace,
399 const String& className) const;
400 mike 1.1
401 private:
402
403 Repository* _repository;
404 };
405
406 RepositoryDeclContext::RepositoryDeclContext(Repository* repository)
407 : _repository(repository)
408 {
409
410 }
411
412 RepositoryDeclContext::~RepositoryDeclContext()
413 {
414
415 }
416
417 QualifierDecl RepositoryDeclContext::lookupQualifierDecl(
418 const String& nameSpace,
419 const String& qualifierName) const
420 {
421 mike 1.1 // Ignore the exception since this routine is only supposed report
422 // whether it can be found:
423
424 try
425 {
426 return _repository->getQualifier(nameSpace, qualifierName);
427 }
428 catch (Exception&)
429 {
430 return QualifierDecl();
431 }
432 }
433
434 ClassDecl RepositoryDeclContext::lookupClassDecl(
435 const String& nameSpace,
436 const String& className) const
437 {
438 // Ignore the exception since this routine is only supposed report
439 // whether it can be found:
440
441 try
442 mike 1.1 {
443 return _repository->getClass(nameSpace, className, false, true, true);
444 }
445 catch (Exception&)
446 {
447 return ClassDecl();
448 }
449 }
450
451 ////////////////////////////////////////////////////////////////////////////////
452 //
453 // Repository
454 //
455 ////////////////////////////////////////////////////////////////////////////////
456
457 Repository::Repository(const String& path)
458 {
459 const char REPOSITORY[] = "/repository";
460 _root = path;
461 _root.append(REPOSITORY);
462
463 mike 1.1 if (!FileSystem::isDirectory(_root))
464 {
465 if (!FileSystem::makeDirectory(_root))
466 throw CannotCreateDirectory(_root);
467 }
468
469 _context = new RepositoryDeclContext(this);
470 }
471
472 Repository::~Repository()
473 {
474
475 }
476
477 ClassDecl Repository::getClass(
478 const String& nameSpace,
479 const String& className,
480 Boolean localOnly,
481 Boolean includeQualifiers,
482 Boolean includeClassOrigin,
483 const Array<String>& propertyList)
484 mike 1.1 {
485 // Form the path to the class:
486
487 String path;
488 _FindClass(_root, nameSpace, className, path);
489
490 // Load the class:
491
492 ClassDecl classDecl;
493 _LoadObject(path, classDecl);
494
495 return ClassDecl(classDecl);
496 }
497
498 InstanceDecl Repository::getInstance(
499 const String& nameSpace,
500 const Reference& instanceName,
501 Boolean localOnly,
502 Boolean includeQualifiers,
503 Boolean includeClassOrigin,
504 const Array<String>& propertyList)
505 mike 1.1 {
506 throw CimException(CimException::NOT_SUPPORTED);
507 return InstanceDecl();
508 }
509
510 void Repository::deleteClass(
511 const String& nameSpace,
512 const String& className)
513 {
514 // Get path of class file:
515
516 String path;
517 _FindClass(_root, nameSpace, className, path);
518
519 // Disallow if the class has subclasses:
520
521 if (_HasSubclasses(_root, nameSpace, className))
522 throw CimException(CimException::CLASS_HAS_CHILDREN);
523
524 // ATTN-C: check to see if the class has instances:
525
526 mike 1.1 // Remove the class:
527
528 if (!FileSystem::removeFile(path))
529 throw FailedToRemoveFile(path);
530 }
531
532 void Repository::deleteInstance(
533 const String& nameSpace,
534 const Reference& instanceName)
535 {
536 throw CimException(CimException::NOT_SUPPORTED);
537 }
538
539 void Repository::createClass(
540 const String& nameSpace,
541 ClassDecl& newClass)
542 {
543 // Form the path to the class:
544
545 String path;
546 const String& className = newClass.getClassName();
547 mike 1.1 const String& superClassName = newClass.getSuperClassName();
548 _MakeNewClassPath(_root, nameSpace, className, superClassName, path);
549
550 if (FileSystem::exists(path))
551 throw CimException(CimException::ALREADY_EXISTS);
552
553 // Validate the new class:
554
555 #if 0
556 newClass.resolve(_context, nameSpace);
557 #endif
558
559 // Save the class:
560
561 _SaveObject(path, newClass);
562 }
563
564 void Repository::createInstance(
565 const String& nameSpace,
566 const InstanceDecl& newInstance)
567 {
568 mike 1.1 throw CimException(CimException::NOT_SUPPORTED);
569 }
570
571 void Repository::modifyClass(
572 const String& nameSpace,
573 ClassDecl& modifiedClass)
574 {
575 // ATTN: need lots of semantic checking here:
576
577 // Get the old class:
578
579 ClassDecl oldClass = getClass(
580 nameSpace, modifiedClass.getClassName(), false, true, true);
581
582 // Disallow changing the name of the super-class:
583
584 if (modifiedClass.getSuperClassName() != oldClass.getSuperClassName())
585 throw CimException(CimException::INVALID_SUPERCLASS);
586
587 // Delete the old class:
588
589 mike 1.1 deleteClass(nameSpace, modifiedClass.getClassName());
590
591 // Create the class again:
592
593 createClass(nameSpace, modifiedClass);
594 }
595
596 void Repository::modifyInstance(
597 const String& nameSpace,
598 const InstanceDecl& modifiedInstance)
599 {
600 throw CimException(CimException::NOT_SUPPORTED);
601 }
602
603 Array<ClassDecl> Repository::enumerateClasses(
604 const String& nameSpace,
605 const String& className,
606 Boolean deepInheritance,
607 Boolean localOnly,
608 Boolean includeQualifiers,
609 Boolean includeClassOrigin)
610 mike 1.1 {
611 Array<String> classNames =
612 enumerateClassNames(nameSpace, className, deepInheritance);
613
614 Array<ClassDecl> result;
615
616 for (Uint32 i = 0; i < classNames.getSize(); i++)
617 {
618 result.append(getClass(nameSpace, classNames[i], localOnly,
619 includeQualifiers, includeClassOrigin));
620 }
621
622 return result;
623 }
624
625 Array<String> Repository::enumerateClassNames(
626 const String& nameSpace,
627 const String& className,
628 Boolean deepInheritance)
629 {
630 // Build the path to the classes directory:
631 mike 1.1
632 const char CLASSES[] = "/classes/";
633 String path;
634 _MakeNameSpacePath(_root, nameSpace, path);
635 path.append(CLASSES);
636
637 if (!FileSystem::isDirectory(path))
638 throw CimException(CimException::INVALID_NAMESPACE);
639
640 if (deepInheritance)
641 {
642 if (className == String::EMPTY)
643 {
644 Array<String> classNames;
645 _AppendSubclassesDeep(path, String(), classNames);
646 return classNames;
647 }
648 else
649 {
650 Array<String> classNames;
651 _AppendSubclassesDeep(path, className, classNames);
652 mike 1.1 return classNames;
653 }
654 }
655 else
656 {
657 if (className == String::EMPTY)
658 {
659 Array<String> classNames;
660 _AppendClassNames(path, "*", "#", classNames);
661 return classNames;
662 }
663 else
664 {
665 Array<String> classNames;
666 _AppendClassNames(path, "*", className, classNames);
667 return classNames;
668 }
669 }
670
671 // Unreachable:
672 return Array<String>();
673 mike 1.1 }
674
675 Array<InstanceDecl> Repository::enumerateInstances(
676 const String& nameSpace,
677 const String& className,
678 Boolean deepInheritance,
679 Boolean localOnly,
680 Boolean includeQualifiers,
681 Boolean includeClassOrigin,
682 const Array<String>& propertyList)
683 {
684 throw CimException(CimException::NOT_SUPPORTED);
685 return Array<InstanceDecl>();
686 }
687
688 Array<String> Repository::enumerateInstanceNames(
689 const String& nameSpace,
690 const String& className)
691 {
692 throw CimException(CimException::NOT_SUPPORTED);
693 return Array<String>();
694 mike 1.1 }
695
696 Array<InstanceDecl> Repository::execQuery(
697 const String& queryLanguage,
698 const String& query)
699 {
700 throw CimException(CimException::NOT_SUPPORTED);
701 return Array<InstanceDecl>();
702 }
703
704 Array<InstanceDecl> Repository::associators(
705 const String& nameSpace,
706 const Reference& objectName,
707 const String& assocClass,
708 const String& resultClass,
709 const String& role,
710 const String& resultRole,
711 Boolean includeQualifiers,
712 Boolean includeClassOrigin,
713 const Array<String>& propertyList)
714 {
715 mike 1.1 throw CimException(CimException::NOT_SUPPORTED);
716 return Array<InstanceDecl>();
717 }
718
719 Array<Reference> Repository::associatorNames(
720 const String& nameSpace,
721 const Reference& objectName,
722 const String& assocClass,
723 const String& resultClass,
724 const String& role,
725 const String& resultRole)
726 {
727 throw CimException(CimException::NOT_SUPPORTED);
728 return Array<Reference>();
729 }
730
731 Array<InstanceDecl> Repository::references(
732 const String& nameSpace,
733 const Reference& objectName,
734 const String& resultClass,
735 const String& role,
736 mike 1.1 Boolean includeQualifiers,
737 Boolean includeClassOrigin,
738 const Array<String>& propertyList)
739 {
740 throw CimException(CimException::NOT_SUPPORTED);
741 return Array<InstanceDecl>();
742 }
743
744 Array<Reference> Repository::referenceNames(
745 const String& nameSpace,
746 const Reference& objectName,
747 const String& resultClass,
748 const String& role)
749 {
750 throw CimException(CimException::NOT_SUPPORTED);
751 return Array<Reference>();
752 }
753
754 Value Repository::getProperty(
755 const String& nameSpace,
756 const Reference& instanceName,
757 mike 1.1 const String& propertyName)
758 {
759 throw CimException(CimException::NOT_SUPPORTED);
760 return Value();
761 }
762
763 void Repository::setProperty(
764 const String& nameSpace,
765 const Reference& instanceName,
766 const String& propertyName,
767 const Value& newValue)
768 {
769 throw CimException(CimException::NOT_SUPPORTED);
770 }
771
772 QualifierDecl Repository::getQualifier(
773 const String& nameSpace,
774 const String& qualifierName)
775 {
776 // Form the path of the qualifier file:
777
778 mike 1.1 String path;
779 _MakeQualfierPath(_root, nameSpace, qualifierName, path);
780
781 // If it does not exist:
782
783 if (!FileSystem::exists(path))
784 throw CimException(CimException::NOT_FOUND);
785
786 // Load the qualifier:
787
788 QualifierDecl qualifierDecl;
789 _LoadObject(path, qualifierDecl);
790
791 return QualifierDecl(qualifierDecl);
792 }
793
794 void Repository::setQualifier(
795 const String& nameSpace,
796 const QualifierDecl& qualifierDecl)
797 {
798 // Form the path of the qualifier:
799 mike 1.1
800 String path;
801 _MakeQualfierPath(_root, nameSpace, qualifierDecl.getName(), path);
802
803 // If the qualifier already exists, delete it:
804
805 if (FileSystem::exists(path))
806 {
807 if (!FileSystem::removeFile(path))
808 throw FailedToRemoveDirectory(path);
809 }
810
811 // Write the qualifier to file:
812
813 _SaveObject(path, qualifierDecl);
814 }
815
816 void Repository::deleteQualifier(
817 const String& nameSpace,
818 const String& qualifierName)
819 {
820 mike 1.1 String path;
821 _MakeQualfierPath(_root, nameSpace, qualifierName, path);
822
823 if (!FileSystem::exists(path))
824 throw CimException(CimException::NOT_FOUND);
825
826 if (!FileSystem::removeFile(path))
827 throw FailedToRemoveFile(path);
828 }
829
830 Array<QualifierDecl> Repository::enumerateQualifiers(
831 const String& nameSpace)
832 {
833 // Build the path to the qualifiers directory:
834
835 const char QUALIFIERS[] = "/qualifiers/";
836 String path;
837 _MakeNameSpacePath(_root, nameSpace, path);
838 path.append(QUALIFIERS);
839
840 if (!FileSystem::isDirectory(path))
841 mike 1.1 throw CimException(CimException::INVALID_NAMESPACE);
842
843 // Get the names of the qualifiers:
844
845 Array<String> qualifierNames;
846
847 if (!FileSystem::getDirectoryContents(path, qualifierNames))
848 throw NoSuchDirectory(path);
849
850 // Load each qualifier into the result array:
851
852 Array<QualifierDecl> result;
853
854 for (Uint32 i = 0, n = qualifierNames.getSize(); i < n; i++)
855 {
856 QualifierDecl tmp = getQualifier(nameSpace, qualifierNames[i]);
857 result.append(tmp);
858 }
859
860 return result;
861 }
862 mike 1.1
863 Value Repository::invokeMethod(
864 const String& nameSpace,
865 const Reference& instanceName,
866 const String& methodName,
867 const Array<Value>& inParameters,
868 Array<Value>& outParameters)
869 {
870 throw CimException(CimException::NOT_SUPPORTED);
871 return Value();
872 }
873
874 ////////////////////////////////////////////////////////////////////////////////
875 //
876 // New methods
877 //
878 ////////////////////////////////////////////////////////////////////////////////
879
880 void Repository::createNameSpace(const String& nameSpace)
881 {
882 String path;
883 mike 1.1 _MakeNameSpacePath(_root, nameSpace, path);
884
885 if (FileSystem::exists(path))
886 throw AlreadyExists(nameSpace);
887
888 if (!FileSystem::makeDirectory(path))
889 throw CannotCreateDirectory(path);
890
891 // Create "./qualifiers" directory:
892
893 String qualifiersDir = path;
894 qualifiersDir.append("/qualifiers");
895
896 if (!FileSystem::makeDirectory(qualifiersDir))
897 throw CannotCreateDirectory(qualifiersDir);
898
899 // Create "./classes" directory:
900
901 String classesDir = path;
902 classesDir.append("/classes");
903
904 mike 1.1 if (!FileSystem::makeDirectory(classesDir))
905 throw CannotCreateDirectory(classesDir);
906
907 // Create "./instances" directory:
908
909 String instancesDir = path;
910 instancesDir.append("/instances");
911
912 if (!FileSystem::makeDirectory(instancesDir))
913 throw CannotCreateDirectory(instancesDir);
914 }
915
916 Array<String> Repository::enumerateNameSpaces() const
917 {
918 Array<String> result;
919
920 if (!FileSystem::getDirectoryContents(_root, result))
921 throw NoSuchDirectory(_root);
922
923 for (Uint32 i = 0, n = result.getSize(); i < n; i++)
924 {
925 mike 1.1 const String& tmp = result[i];
926
927 for (Char16* p = (Char16*)tmp.getData(); *p; p++)
928 {
929 if (*p == '#')
930 *p = '/';
931 }
932 }
933
934 return result;
935 }
936
937 PEGASUS_NAMESPACE_END
|