1 karl 1.23 //%2003////////////////////////////////////////////////////////////////////////
|
2 mike 1.16 //
|
3 karl 1.23 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Development
4 // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
|
7 mike 1.16 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
9 kumpf 1.20 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
12 mike 1.16 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
|
15 kumpf 1.20 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
16 mike 1.16 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
17 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
18 kumpf 1.20 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
21 mike 1.16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24 //==============================================================================
25 //
26 // Author: Mike Brasher (mbrasher@bmc.com)
27 //
|
28 kumpf 1.22 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
29 // (carolann_graves@hp.com)
|
30 mike 1.16 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
33 #include <Pegasus/Common/String.h>
34 #include <Pegasus/Common/HashTable.h>
35 #include <Pegasus/Common/Dir.h>
|
36 kumpf 1.22 #include <Pegasus/Common/XmlWriter.h>
|
37 mike 1.16 #include "InheritanceTree.h"
38
39 PEGASUS_NAMESPACE_BEGIN
40
41 PEGASUS_USING_STD;
42
43 ////////////////////////////////////////////////////////////////////////////////
44 //
45 // NoCaseEqualFunc
46 //
47 ////////////////////////////////////////////////////////////////////////////////
48
49 struct NoCaseEqualFunc
50 {
51 static Boolean equal(const String& x, const String& y)
52 {
53 return String::equalNoCase(x, y);
54 }
55 };
56
57 ////////////////////////////////////////////////////////////////////////////////
58 mike 1.16 //
59 // InheritanceTreeNode
60 //
61 ////////////////////////////////////////////////////////////////////////////////
62
63 struct InheritanceTreeNode
64 {
|
65 kumpf 1.22 InheritanceTreeNode(const CIMName& className);
|
66 mike 1.16
67 void addSubClass(InheritanceTreeNode* subClass);
68
69 Boolean removeSubClass(InheritanceTreeNode* subClass);
70
71 void getSubClassNames(
|
72 kumpf 1.22 Array<CIMName>& subClassNames,
|
73 mike 1.16 Boolean deepInheritance);
74
|
75 kumpf 1.22 void getSuperClassNames(Array<CIMName>& superClassNames);
|
76 mike 1.16
77 void print(PEGASUS_STD(ostream)& os) const;
78
|
79 kumpf 1.22 Boolean isSubClass(const CIMName& className) const;
|
80 mike 1.16
|
81 kumpf 1.22 CIMName className;
|
82 mike 1.16 InheritanceTreeNode* superClass;
83 InheritanceTreeNode* sibling;
84 InheritanceTreeNode* subClasses;
85 Boolean provisional;
86 };
87
|
88 kumpf 1.22 InheritanceTreeNode::InheritanceTreeNode(const CIMName& className)
|
89 mike 1.16 : className(className), superClass(0),
90 sibling(0), subClasses(0), provisional(true)
91 {
92
93 }
94
95 void InheritanceTreeNode::addSubClass(InheritanceTreeNode* subClass)
96 {
97 subClass->superClass = this;
98 subClass->sibling = subClasses;
99 subClasses = subClass;
100 }
101
102 Boolean InheritanceTreeNode::removeSubClass(InheritanceTreeNode* subClass)
103 {
104 InheritanceTreeNode* prev = 0;
105
106 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
107 {
108 if (p == subClass)
109 {
110 mike 1.16 if (prev)
111 prev->sibling = subClass->sibling;
112 else
113 subClasses = subClass->sibling;
114
115 return true;
116 }
117 prev = p;
118 }
119
120 return false;
121 }
122
123 void InheritanceTreeNode::getSubClassNames(
|
124 kumpf 1.22 Array<CIMName>& subClassNames,
|
125 mike 1.16 Boolean deepInheritance)
126 {
127 // For each subClass:
128
129 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
130 {
|
131 mday 1.19
|
132 mike 1.16 subClassNames.append(p->className);
133
134 if (deepInheritance)
135 {
136 p->getSubClassNames(subClassNames, true);
137 }
138 }
139 }
140
|
141 kumpf 1.22 Boolean InheritanceTreeNode::isSubClass(const CIMName& className_) const
|
142 mike 1.16 {
|
143 kumpf 1.22 if (className.equal (className_))
|
144 mike 1.16 return true;
145
146 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
147 {
|
148 kumpf 1.22 if (p->className.equal (className_))
|
149 mike 1.16 return true;
150 }
151
152 return false;
153 }
154
|
155 kumpf 1.22 void InheritanceTreeNode::getSuperClassNames(Array<CIMName>& superClassNames)
|
156 mike 1.16 {
157 // For each superClass:
158
159 for (InheritanceTreeNode* p = superClass; p; p = p->superClass)
160 {
161 superClassNames.append(p->className);
162 p->getSuperClassNames(superClassNames);
163 }
164 }
165
166 void InheritanceTreeNode::print(PEGASUS_STD(ostream)& os) const
167 {
168 os << className << " : " ;
|
169 kumpf 1.22 os << (superClass ? superClass->className : CIMName ());
|
170 mike 1.16
171 os << " { ";
172
173 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
174 os << p->className << ' ';
175
176 os << "}" << endl;
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180 //
181 // InheritanceTreeRep
182 //
183 ////////////////////////////////////////////////////////////////////////////////
184
|
185 sage 1.18
|
186 mike 1.16 struct InheritanceTreeRep
187 {
188 typedef HashTable<String, InheritanceTreeNode*,
|
189 sage 1.18 NoCaseEqualFunc, HashFunc<String> > Table;
|
190 mike 1.16 Table table;
191 };
192
193 ////////////////////////////////////////////////////////////////////////////////
194 //
195 // InheritanceTree
196 //
197 ////////////////////////////////////////////////////////////////////////////////
198
199 InheritanceTree::InheritanceTree()
200 {
201 _rep = new InheritanceTreeRep;
202 }
203
204 InheritanceTree::~InheritanceTree()
205 {
|
206 sage 1.18 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
207 delete i.value();
208
|
209 mike 1.16 delete _rep;
210 }
211
212 void InheritanceTree::insert(
213 const String& className,
214 const String& superClassName)
215 {
216 // ATTN: need found flag!
217
218 // -- Insert superclass:
219
220 InheritanceTreeNode* superClassNode = 0;
221
|
222 kumpf 1.22 if ((superClassName.size()) &&
|
223 mike 1.16 !_rep->table.lookup(superClassName, superClassNode))
224 {
225 superClassNode = new InheritanceTreeNode(superClassName);
226 _rep->table.insert(superClassName, superClassNode);
227 }
228
229 // -- Insert class:
230
231 InheritanceTreeNode* classNode = 0;
232
233 if (!_rep->table.lookup(className, classNode))
234 {
235 classNode = new InheritanceTreeNode(className);
236 _rep->table.insert(className, classNode);
237 }
238
239 classNode->provisional = false;
240
241 // -- Link the class and superclass nodes:
242
243 if (superClassNode)
244 mike 1.16 superClassNode->addSubClass(classNode);
245 }
246
247 void InheritanceTree::insertFromPath(const String& path)
248 {
249 for (Dir dir(path); dir.more(); dir.next())
250 {
251 String fileName = dir.getName();
252
253 // Ignore the current and parent directories.
254
255 if (fileName == "." || fileName == "..")
256 continue;
257
258 Uint32 dot = fileName.find('.');
259
260 // Ignore files without dots in them:
261
|
262 kumpf 1.21 if (dot == PEG_NOT_FOUND)
|
263 mike 1.16 continue;
264
265 String className = fileName.subString(0, dot);
266 String superClassName = fileName.subString(dot + 1);
267
268 if (superClassName == "#")
269 superClassName.clear();
270
271 insert(className, superClassName);
272 }
273 }
274
275 void InheritanceTree::check() const
276 {
277 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
278 {
279 if (i.value()->provisional)
|
280 kumpf 1.22 throw InvalidInheritanceTree(i.value()->className.getString());
|
281 mike 1.16 }
282 }
283
284 Boolean InheritanceTree::getSubClassNames(
|
285 kumpf 1.22 const CIMName& className,
|
286 mike 1.16 Boolean deepInheritance,
|
287 kumpf 1.22 Array<CIMName>& subClassNames) const
|
288 mike 1.16 {
289
|
290 mday 1.19 // -- Case 1: className is empty: get all class names (if deepInheritance)
291 // -- or just root class names (if not deepInheritance).
|
292 kumpf 1.22 if (className.isNull())
|
293 mday 1.19 {
294 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start();i;i++)
295 {
296 if (deepInheritance)
297 {
298 // Append all classes:
299
300 subClassNames.append(i.key());
301 }
302 else if (!i.value()->superClass)
303 {
304 // Just append root classes:
305
306 subClassNames.append(i.key());
307 }
308 }
309 return true;
310 }
311
312 // -- Case 2: className non-empty: get names of classes descendent from
313 // -- the given class.
314 mday 1.19
315 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
316 {
|
317 kumpf 1.22 if (className.equal (i.key()))
|
318 mday 1.19 {
319 i.value()->getSubClassNames(subClassNames, deepInheritance);
320 return true;
321 }
322 }
323
324 // Not found!
325 return false;
|
326 mike 1.16 }
327
|
328 mike 1.17 Boolean InheritanceTree::isSubClass(
|
329 kumpf 1.22 const CIMName& class1,
330 const CIMName& class2) const
|
331 mike 1.16 {
332 InheritanceTreeNode* node = 0;
333
|
334 kumpf 1.22 if (!_rep->table.lookup(class1.getString(), node))
|
335 mike 1.16 return false;
336
|
337 kumpf 1.22 return node->isSubClass(class2.getString());
|
338 mike 1.16 }
339
340 Boolean InheritanceTree::getSuperClassNames(
|
341 kumpf 1.22 const CIMName& className,
342 Array<CIMName>& superClassNames) const
|
343 mike 1.16 {
344 InheritanceTreeNode* classNode;
345
|
346 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
347 mike 1.16 {
348 classNode->getSuperClassNames(superClassNames);
349 return true;
350 }
351
352 return false;
353 }
354
355 Boolean InheritanceTree::getSuperClass(
|
356 kumpf 1.22 const CIMName& className,
357 CIMName& superClassName) const
|
358 mike 1.16 {
359 InheritanceTreeNode* classNode;
360
|
361 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
362 mike 1.16 {
363 if (classNode->superClass)
364 {
365 superClassName = classNode->superClass->className;
366 }
367 else
368 {
369 superClassName.clear();
370 }
371
372 return true;
373 }
374
375 return false;
376 }
377
378 Boolean InheritanceTree::hasSubClasses(
|
379 kumpf 1.22 const CIMName& className,
|
380 mike 1.16 Boolean& hasSubClasses) const
381 {
382 InheritanceTreeNode* node = 0;
383
|
384 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
|
385 mike 1.16 return false;
386
387 hasSubClasses = node->subClasses != 0;
388 return true;
389 }
390
|
391 kumpf 1.22 Boolean InheritanceTree::containsClass(const CIMName& className) const
|
392 mike 1.16 {
|
393 kumpf 1.22 return _rep->table.contains(className.getString());
|
394 mike 1.16 }
395
|
396 kumpf 1.22 void InheritanceTree::remove(const CIMName& className)
|
397 mike 1.16 {
398 // -- Lookup the node:
399
400 InheritanceTreeNode* node = 0;
401
|
402 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
403 throw PEGASUS_CIM_EXCEPTION
404 (CIM_ERR_INVALID_CLASS, className.getString());
|
405 mike 1.16
406 // -- Disallow if is has any subclasses:
407
408 if (node->subClasses)
|
409 kumpf 1.22 throw PEGASUS_CIM_EXCEPTION
410 (CIM_ERR_CLASS_HAS_CHILDREN, className.getString());
|
411 mike 1.16
412 // -- Remove as child of superclass:
413
414 InheritanceTreeNode* superClass = node->superClass;
415
416 if (superClass)
417 {
418 Boolean result = superClass->removeSubClass(node);
419 PEGASUS_ASSERT(result);
420 }
421
422 // -- Remove from the hash table and delete:
423
|
424 kumpf 1.22 Boolean result = _rep->table.remove(className.getString());
|
425 mike 1.16 PEGASUS_ASSERT(result);
426 delete node;
427 }
428
429 void InheritanceTree::print(PEGASUS_STD(ostream)& os) const
430 {
431 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
432 i.value()->print(os);
433 }
434
435 PEGASUS_NAMESPACE_END
|