3 kumpf 1.17 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
7 kumpf 1.17 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
19 mike 1.15 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
26 // Modified By:
27 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
30 #ifndef Pegasus_InheritanceTree_h
31 #define Pegasus_InheritanceTree_h
32
33 #include <iostream>
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/String.h>
36 #include <Pegasus/Common/Exception.h>
37
38 PEGASUS_NAMESPACE_BEGIN
39
40 mike 1.15 struct InheritanceTreeRep;
41
42 /** The InheritanceTree class tracks inheritance relationships of CIM classes.
43
44 This class is a memory resident version of the repository's persistent
45 inheritance information (represented using file names). The InheritanceTree
46 provides O(1) access (via hashing) to any class in the inheritance tree.
47
48 The inheritance tree provides methods for interrogating certain kinds of
49 information about a class, including:
50
51 <ul>
52 <li>the superclass</li>
53 <li>the subclasses</li>
54 <li>the descendent classes</li>
55 </ul>
56
57 The insert() method is used to build up an InheritanceTree. The insert()
58 method is called for each class-subclass relationship. For example, consider
59 the following list of class-subclass pairs:
60
61 mike 1.15 <pre>
62 { "D", "B" }
63 { "E", "B" }
64 { "B", "A" }
65 { "C", "A" }
66 { "F", "C" }
67 </pre>
68
69 These pairs specify the following inheritance tree:
70
71 <pre>
72 A
73 / \
74 B C
75 / \ \
76 D E F
77 </pre>
78
79 The pairs above may be used to build a class tree as follows:
80
81 <pre>
82 mike 1.15 InheritanceTree it;
83 it.insert("D", "B");
84 it.insert("E", "B");
85 it.insert("B", "A");
86 it.insert("C", "A");
87 it.insert("F", "C");
88 it.insert("A", "");
89 it.check();
90 </pre>
91
92 The check() method determines whether insert() was called for every class
93 used as a superclass. In the following example, check() would fail (and
94 throw and exception) since the "B" class is passed as a superclass (second
95 argument) in two insert() calls but was never passed as the class itself
96 (first argument) in any insert() call:
97
98 <pre>
99 InheritanceTree it;
100 it.insert("D", "B");
101 it.insert("E", "B");
102 it.insert("C", "A");
103 mike 1.15 it.insert("F", "C");
104 it.insert("A", "");
105 it.check();
106 </pre>
107
108 In this case, check() throws an InvalidInheritanceTree exception.
109
110 The InheritanceTree may be printed by calling the print() method.
111
112 The insertFromPath() method is used to build up an InheritanceTree from
113 the file names in a certain directory as used by the CIMRepository. The
114 CIMRepository contains a disk file per class and the name has this form:
115
116 <pre>
117 <ClassName>.<SuperClassName>
118 </pre>
119
120 For example, a class called "ThisClass" with super class "ThatClass"
121 has this name:
122
123 <pre>
124 mike 1.15 ThisClass.ThisClass
125 </pre>
126
127 The file or course contains the XML encoding of the ThisClass class (which
128 is irrelevant for the InheritanceTree). A root class (with no superclass
129 has the following form):
130
131 <pre>
132 <ClassName>.#
133 </pre>
134
135 Suppose that ThatClass is a root class; then its file name is:
136
137 <pre>
138 ThatClass.#
139 </pre>
140
141 It must be obvious by now that the insertFromPath() method just scans
142 the file names in a directory and calls insert() for each one (splitting
143 the class name from superclass name and translating '#' to an empty string).
144
145 mike 1.15 The insertFromPath() method does NOT call check(), so it still must be
146 called to verify the InheritanceTree.
147 */
148 class PEGASUS_REPOSITORY_LINKAGE InheritanceTree
149 {
150 public:
151
152 /** Default constructor. */
153 InheritanceTree();
154
155 /** Destructor. */
156 ~InheritanceTree();
157
158 /** Inserts a class-subclass relationship into the inheritance three.
159 Note that a class CAN be inserted before its superclass, in which case
160 a provisional entry is made for the superclass and flagged as such;
161 when the superclass is later inserted, the provisional flag is cleared.
162 @param className - name of class being inserted.
163 @param superClassName - name of super class of class.
164 */
165 void insert(const String& className, const String& superClassName);
166 mike 1.15
167 /** Scan directory for file names of the form <ClassName>.<SuperClass> and
168 call insert on insert for each one. Note that root classes (classes with
169 no superclass) will use "#" for a SuperClass name.
170 @param path - directory that contains files describing inheritance
171 infoformation.
172 @exception throws CannotOpenDirectory is invalid path specifies an
173 invalid directory.
174 */
175 void insertFromPath(const String& path);
176
177 /** Checks that every superClassName passed to insert() was also passed
178 as a className argument to insert(). In other words, it checks that
179 there are no provisional entries as described in the insert() method.
180 @exception InvalidInheritanceTree
181 */
182 void check() const;
183
184 /** Get subclass names of the given class.
185 @param className - class whose subclass names will be gotten. If
186 className is empty, all classnames are returned.
187 mike 1.15 @param deepInheritance - if true all descendent classes of class
188 are returned. If className is empty, only root classes are returned.
189 @param subClassNames - output argument to hold subclass names.
190 @return true on success. False if no such class.
191 */
192 Boolean getSubClassNames(
193 const String& className,
194 Boolean deepInheritance,
195 Array<String>& subClassNames) const;
196
197 /** Returns true if class1 is a subclass of class2.
198 */
|
200 mike 1.15
201 /** Get the names of all superclasses of this class (direct and indirect).
202 */
203 Boolean getSuperClassNames(
204 const String& className,
205 Array<String>& subClassNames) const;
206
207 /** Get the superclass of the given class.
208 @param className name of class.
209 @param superClassName name of superclass upon return.
210 @return true if class was found; false otherwise.
211 */
212 Boolean getSuperClass(
213 const String& className,
214 String& superClassName) const;
215
216 /** Returns true if the given class has sub-classes. */
217 Boolean hasSubClasses(
218 const String& className,
219 Boolean& hasSubClasses) const;
220
221 mike 1.15 /** Returns true if this inhertance tree contains the given class. */
222 Boolean containsClass(const String& className) const;
223
224 /** Removes the given class from the class graph.
225 @exception CIMException(CIM_ERR_CLASS_HAS_CHILDREN)
226 @exception CIMException(CIM_ERR_INVALID_CLASS)
227 */
228 void remove(const String& className);
229
230 /** Prints the class */
231 void print(PEGASUS_STD(ostream)& os) const;
232
233 private:
234
235 InheritanceTree(const InheritanceTree&) { }
236
237 InheritanceTree& operator=(const InheritanceTree&) { return *this; }
238
239 InheritanceTreeRep* _rep;
240 };
241
242 mike 1.15 /** The InvalidInheritanceTree exception is thrown when the
243 InheritanceTreeRep::check() method determines that an inheritance tree
244 was not fully specified (when any class was passed as a superClassName
245 argument to insert() but never as a className argument.
246 */
247 class InvalidInheritanceTree : public Exception
248 {
249 public:
250
251 InvalidInheritanceTree(const String& className)
252 : Exception("Invalid inheritance tree: unknown class: " + className) { }
253 };
254
255 PEGASUS_NAMESPACE_END
256
257 #endif /* Pegasus_InheritanceTree_h */
|