1 karl 1.35 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.16 //
|
3 karl 1.27 // 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 karl 1.23 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.27 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.29 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.35 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.16 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.20 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.16 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
|
21 kumpf 1.20 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.16 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.20 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
|
34 kumpf 1.22 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
35 // (carolann_graves@hp.com)
|
36 vijay.eli 1.30 // Vijay Eli, IBM (vijayeli@in.ibm.com) for bug#3352
|
37 mike 1.16 //
38 //%/////////////////////////////////////////////////////////////////////////////
39
40 #include <Pegasus/Common/String.h>
41 #include <Pegasus/Common/HashTable.h>
42 #include <Pegasus/Common/Dir.h>
|
43 kumpf 1.22 #include <Pegasus/Common/XmlWriter.h>
|
44 chuck 1.24 #include <Pegasus/Common/CommonUTF.h>
|
45 r.kieninger 1.33 #include <Pegasus/Common/CIMNameUnchecked.h>
|
46 mike 1.16 #include "InheritanceTree.h"
47
|
48 schuur 1.25 #if 0
49 #undef PEG_METHOD_ENTER
50 #undef PEG_METHOD_EXIT
51 #define PEG_METHOD_ENTER(x,y) cout<<"--- Enter: "<<y<<endl;
52 #define PEG_METHOD_EXIT()
53 #endif
54
|
55 mike 1.16 PEGASUS_NAMESPACE_BEGIN
56
57 PEGASUS_USING_STD;
58
59 ////////////////////////////////////////////////////////////////////////////////
60 //
61 // NoCaseEqualFunc
62 //
63 ////////////////////////////////////////////////////////////////////////////////
64
65 struct NoCaseEqualFunc
66 {
67 static Boolean equal(const String& x, const String& y)
68 {
69 return String::equalNoCase(x, y);
70 }
71 };
72
73 ////////////////////////////////////////////////////////////////////////////////
74 //
|
75 schuur 1.25 // InheritanceTreeRep
76 //
77 ////////////////////////////////////////////////////////////////////////////////
78
|
79 marek 1.26 struct InheritanceTreeNode;
|
80 schuur 1.25
81 struct InheritanceTreeRep
82 {
|
83 mike 1.32 typedef HashTable<
84 String, InheritanceTreeNode*, NoCaseEqualFunc, HashLowerCaseFunc> Table;
|
85 schuur 1.25 Table table;
|
86 mike 1.32
87 // Tradeoff: chosing a larger value decreases hash lookup time but
88 // increases iteration (which seems to be the dominant operations).
89 // This power of two (256) seems to produce the best results.
90
91 InheritanceTreeRep() : table(256)
92 {
93 }
|
94 schuur 1.25 };
95
96 ////////////////////////////////////////////////////////////////////////////////
97 //
|
98 mike 1.16 // InheritanceTreeNode
99 //
100 ////////////////////////////////////////////////////////////////////////////////
101
|
102 schuur 1.25 class NameSpace;
103
104 struct InheritanceTreeExt
105 {
106 InheritanceTreeExt(NameSpace* t, InheritanceTreeNode* itn)
107 : tag(t), node(itn) {}
108 NameSpace* tag;
109 InheritanceTreeNode* node;
110 };
111
112
|
113 mike 1.16 struct InheritanceTreeNode
114 {
|
115 kumpf 1.22 InheritanceTreeNode(const CIMName& className);
|
116 mike 1.16
117 void addSubClass(InheritanceTreeNode* subClass);
118
119 Boolean removeSubClass(InheritanceTreeNode* subClass);
120
121 void getSubClassNames(
|
122 kumpf 1.22 Array<CIMName>& subClassNames,
|
123 schuur 1.25 Boolean deepInheritance,
124 NameSpace *tag=0);
|
125 mike 1.16
|
126 kumpf 1.22 void getSuperClassNames(Array<CIMName>& superClassNames);
|
127 mike 1.16
128 void print(PEGASUS_STD(ostream)& os) const;
|
129 schuur 1.25 #if 0
|
130 kumpf 1.22 Boolean isSubClass(const CIMName& className) const;
|
131 schuur 1.25 #endif
|
132 kumpf 1.22 CIMName className;
|
133 mike 1.16 InheritanceTreeNode* superClass;
134 InheritanceTreeNode* sibling;
|
135 schuur 1.25 union {
|
136 mike 1.16 InheritanceTreeNode* subClasses;
|
137 schuur 1.25 Array<InheritanceTreeExt*>* extNodes;
138 };
|
139 mike 1.16 Boolean provisional;
|
140 schuur 1.25 Boolean extension;
|
141 mike 1.16 };
142
|
143 kumpf 1.22 InheritanceTreeNode::InheritanceTreeNode(const CIMName& className)
|
144 mike 1.16 : className(className), superClass(0),
|
145 schuur 1.25 sibling(0), subClasses(0), provisional(true), extension(false)
|
146 mike 1.16 {
147 }
148
149 void InheritanceTreeNode::addSubClass(InheritanceTreeNode* subClass)
150 {
151 subClass->superClass = this;
152 subClass->sibling = subClasses;
153 subClasses = subClass;
154 }
155
156 Boolean InheritanceTreeNode::removeSubClass(InheritanceTreeNode* subClass)
157 {
158 InheritanceTreeNode* prev = 0;
159
160 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
161 {
162 if (p == subClass)
163 {
164 if (prev)
165 prev->sibling = subClass->sibling;
166 else
167 mike 1.16 subClasses = subClass->sibling;
|
168 schuur 1.25
|
169 mike 1.16 return true;
170 }
171 prev = p;
172 }
173
174 return false;
175 }
176
177 void InheritanceTreeNode::getSubClassNames(
|
178 schuur 1.25 Array<CIMName>& subClassNames,
179 Boolean deepInheritance,
180 NameSpace *ns)
|
181 mike 1.16 {
182 // For each subClass:
183
|
184 schuur 1.25 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling) {
185 if (p->extension) {
186 for (int j=0,m=p->extNodes->size(); j<m; j++) {
187 InheritanceTreeExt *itx=(*(p->extNodes))[j];
188 subClassNames.append(p->className);
189 if (!ns) {
190 InheritanceTreeNode* itn=itx->node;
191 itn->getSubClassNames(subClassNames, deepInheritance, ns);
192 }
193 else if (itx->tag==ns) {
194 InheritanceTreeNode* itn=itx->node;
195 itn->getSubClassNames(subClassNames, deepInheritance, ns);
196 break;
197 }
198 }
199 }
200
201 else {
202 subClassNames.append(p->className);
203 if (deepInheritance) {
204 p->getSubClassNames(subClassNames, true, ns);
205 schuur 1.25 }
|
206 mike 1.16 }
207 }
208 }
209
|
210 schuur 1.25 #if 0
|
211 kumpf 1.22 Boolean InheritanceTreeNode::isSubClass(const CIMName& className_) const
|
212 mike 1.16 {
|
213 kumpf 1.22 if (className.equal (className_))
|
214 mike 1.16 return true;
215
216 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
217 {
|
218 kumpf 1.22 if (p->className.equal (className_))
|
219 mike 1.16 return true;
220 }
221
222 return false;
223 }
|
224 schuur 1.25 #endif
|
225 mike 1.16
|
226 kumpf 1.22 void InheritanceTreeNode::getSuperClassNames(Array<CIMName>& superClassNames)
|
227 mike 1.16 {
228 // For each superClass:
229
230 for (InheritanceTreeNode* p = superClass; p; p = p->superClass)
231 {
232 superClassNames.append(p->className);
|
233 schuur 1.25 // p->getSuperClassNames(superClassNames);
|
234 mike 1.16 }
235 }
236
237 void InheritanceTreeNode::print(PEGASUS_STD(ostream)& os) const
238 {
239 os << className << " : " ;
|
240 kumpf 1.22 os << (superClass ? superClass->className : CIMName ());
|
241 mike 1.16
242 os << " { ";
243
244 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
245 os << p->className << ' ';
246
247 os << "}" << endl;
248 }
249
250 ////////////////////////////////////////////////////////////////////////////////
251 //
252 // InheritanceTree
253 //
254 ////////////////////////////////////////////////////////////////////////////////
255
256 InheritanceTree::InheritanceTree()
257 {
258 _rep = new InheritanceTreeRep;
259 }
260
261 InheritanceTree::~InheritanceTree()
262 mike 1.16 {
|
263 sage 1.18 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
264 delete i.value();
265
|
266 mike 1.16 delete _rep;
267 }
|
268 schuur 1.25 void InheritanceTree::insert(
269 const String& className,
270 const String& superClassName,
271 InheritanceTree& parentTree,
272 NameSpace *tag)
273 {
274 InheritanceTreeNode* superClassNode = 0;
275
276 if ((superClassName.size()) &&
|
277 karl 1.31 !parentTree._rep->table.lookup(superClassName, superClassNode)) {
|
278 r.kieninger 1.33 superClassNode =
279 new InheritanceTreeNode(CIMNameUnchecked(superClassName));
|
280 karl 1.31 parentTree._rep->table.insert(superClassName, superClassNode);
|
281 schuur 1.25 }
282
283 InheritanceTreeNode* extNode = 0;
284
285 if (!parentTree._rep->table.lookup(className, extNode)) {
|
286 r.kieninger 1.33 extNode = new InheritanceTreeNode(CIMNameUnchecked(className));
|
287 karl 1.31 parentTree._rep->table.insert(className, extNode);
288 extNode->extension=true;
289 extNode->extNodes=new Array<InheritanceTreeExt*>;
|
290 schuur 1.25 }
291
292 extNode->provisional = false;
293
294 if (superClassNode)
|
295 karl 1.31 superClassNode->addSubClass(extNode);
|
296 schuur 1.25
297 InheritanceTreeNode* classNode = 0;
298
299 if (!_rep->table.lookup(className, classNode)) {
|
300 karl 1.31 classNode = new InheritanceTreeNode(className);
301 _rep->table.insert(className, classNode);
|
302 schuur 1.25 }
303
304 extNode->extNodes->append(new InheritanceTreeExt(tag,classNode));
305
306 classNode->superClass = superClassNode;
|
307 karl 1.31 /* temp comment out this code from bug 3352. See bug 3498 for reason
|
308 vijay.eli 1.30 if(extNode)
309 {
|
310 karl 1.31 for(int i=0, m=extNode->extNodes->size(); i < m; i++)
311 if ((*extNode->extNodes)[i])
312 delete (*(extNode->extNodes))[i];
|
313 vijay.eli 1.30 delete extNode;
|
314 karl 1.31 }
315 extNode = NULL;*/
316
|
317 schuur 1.25 }
|
318 mike 1.16
319 void InheritanceTree::insert(
320 const String& className,
321 const String& superClassName)
322 {
323 // ATTN: need found flag!
324
325 // -- Insert superclass:
326
327 InheritanceTreeNode* superClassNode = 0;
328
|
329 kumpf 1.22 if ((superClassName.size()) &&
|
330 mike 1.16 !_rep->table.lookup(superClassName, superClassNode))
331 {
|
332 r.kieninger 1.33 superClassNode =
333 new InheritanceTreeNode(CIMNameUnchecked(superClassName));
|
334 mike 1.16 _rep->table.insert(superClassName, superClassNode);
335 }
336
337 // -- Insert class:
338
339 InheritanceTreeNode* classNode = 0;
340
341 if (!_rep->table.lookup(className, classNode))
342 {
|
343 r.kieninger 1.33 classNode = new InheritanceTreeNode(CIMNameUnchecked(className));
|
344 mike 1.16 _rep->table.insert(className, classNode);
345 }
346
347 classNode->provisional = false;
348
349 // -- Link the class and superclass nodes:
350
351 if (superClassNode)
352 superClassNode->addSubClass(classNode);
353 }
354
|
355 schuur 1.25 void InheritanceTree::insertFromPath(const String& path,
356 InheritanceTree* parentTree,
357 NameSpace *ns)
|
358 mike 1.16 {
359 for (Dir dir(path); dir.more(); dir.next())
360 {
361 String fileName = dir.getName();
362
363 // Ignore the current and parent directories.
364
365 if (fileName == "." || fileName == "..")
366 continue;
367
368 Uint32 dot = fileName.find('.');
369
370 // Ignore files without dots in them:
371
|
372 kumpf 1.21 if (dot == PEG_NOT_FOUND)
|
373 mike 1.16 continue;
374
375 String className = fileName.subString(0, dot);
376 String superClassName = fileName.subString(dot + 1);
377
378 if (superClassName == "#")
379 superClassName.clear();
380
|
381 bafna.mukesh 1.28
|
382 chuck 1.24 #ifdef PEGASUS_REPOSITORY_ESCAPE_UTF8
|
383 schuur 1.25 if (ns) insert(escapeStringDecoder(className), escapeStringDecoder(superClassName),
384 *parentTree,ns);
385 else insert(escapeStringDecoder(className),
386 escapeStringDecoder(superClassName));
|
387 chuck 1.24 #else
|
388 schuur 1.25 if (ns) insert(className, superClassName, *parentTree,ns);
389 else insert(className,superClassName);
|
390 chuck 1.24 #endif
|
391 mike 1.16 }
392 }
393
394 void InheritanceTree::check() const
395 {
396 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
397 {
398 if (i.value()->provisional)
|
399 kumpf 1.22 throw InvalidInheritanceTree(i.value()->className.getString());
|
400 mike 1.16 }
401 }
402
403 Boolean InheritanceTree::getSubClassNames(
|
404 kumpf 1.22 const CIMName& className,
|
405 mike 1.16 Boolean deepInheritance,
|
406 schuur 1.25 Array<CIMName>& subClassNames,
407 NameSpace *ns) const
|
408 mike 1.16 {
409
|
410 mday 1.19 // -- Case 1: className is empty: get all class names (if deepInheritance)
411 // -- or just root class names (if not deepInheritance).
|
412 schuur 1.25
413 if (className.isNull()) {
414
415 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start();i;i++) {
416 InheritanceTreeNode *itn=i.value();
417 if (itn->extension) {
418 if (!ns) continue;
419 for (int j=0,m=itn->extNodes->size(); j<m; j++) {
420 InheritanceTreeExt *itx=(*(itn->extNodes))[j];
421 if (itx->tag==ns) {
422 InheritanceTreeNode *itn=itx->node;
423 if (deepInheritance) {
|
424 r.kieninger 1.33 subClassNames.append(CIMNameUnchecked(i.key()));
|
425 schuur 1.25 itn->getSubClassNames(subClassNames, deepInheritance, ns);
426 }
427 else if (!i.value()->superClass)
|
428 r.kieninger 1.33 subClassNames.append(CIMNameUnchecked(i.key()));
|
429 schuur 1.25 break;
430 }
431 }
432 }
433
434 else if (deepInheritance) {
|
435 mday 1.19 // Append all classes:
|
436 r.kieninger 1.33 subClassNames.append(CIMNameUnchecked(i.key()));
|
437 mday 1.19 }
|
438 schuur 1.25 else if (!i.value()->superClass) {
|
439 mday 1.19 // Just append root classes:
|
440 r.kieninger 1.33 subClassNames.append(CIMNameUnchecked(i.key()));
|
441 mday 1.19 }
442 }
443 return true;
444 }
|
445 schuur 1.25
|
446 mday 1.19 // -- Case 2: className non-empty: get names of classes descendent from
447 // -- the given class.
|
448 schuur 1.25
449 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++) {
|
450 r.kieninger 1.33 if (className.equal (CIMNameUnchecked(i.key()))) {
|
451 schuur 1.25 i.value()->getSubClassNames(subClassNames, deepInheritance, ns);
|
452 mday 1.19 return true;
453 }
454 }
455
456 // Not found!
457 return false;
|
458 mike 1.16 }
|
459 schuur 1.25 #if 0
|
460 mike 1.17 Boolean InheritanceTree::isSubClass(
|
461 kumpf 1.22 const CIMName& class1,
462 const CIMName& class2) const
|
463 mike 1.16 {
464 InheritanceTreeNode* node = 0;
465
|
466 kumpf 1.22 if (!_rep->table.lookup(class1.getString(), node))
|
467 mike 1.16 return false;
468
|
469 kumpf 1.22 return node->isSubClass(class2.getString());
|
470 mike 1.16 }
|
471 schuur 1.25 #endif
|
472 mike 1.16
473 Boolean InheritanceTree::getSuperClassNames(
|
474 kumpf 1.22 const CIMName& className,
475 Array<CIMName>& superClassNames) const
|
476 mike 1.16 {
477 InheritanceTreeNode* classNode;
478
|
479 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
480 mike 1.16 {
481 classNode->getSuperClassNames(superClassNames);
482 return true;
483 }
484
485 return false;
486 }
487
488 Boolean InheritanceTree::getSuperClass(
|
489 kumpf 1.22 const CIMName& className,
490 CIMName& superClassName) const
|
491 mike 1.16 {
492 InheritanceTreeNode* classNode;
493
|
494 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
495 mike 1.16 {
496 if (classNode->superClass)
497 {
498 superClassName = classNode->superClass->className;
499 }
500 else
501 {
502 superClassName.clear();
503 }
504
505 return true;
506 }
507
508 return false;
509 }
510
511 Boolean InheritanceTree::hasSubClasses(
|
512 kumpf 1.22 const CIMName& className,
|
513 mike 1.16 Boolean& hasSubClasses) const
514 {
515 InheritanceTreeNode* node = 0;
516
|
517 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
|
518 mike 1.16 return false;
519
520 hasSubClasses = node->subClasses != 0;
521 return true;
522 }
523
|
524 kumpf 1.22 Boolean InheritanceTree::containsClass(const CIMName& className) const
|
525 mike 1.16 {
|
526 kumpf 1.22 return _rep->table.contains(className.getString());
|
527 mike 1.16 }
528
|
529 schuur 1.25 void InheritanceTree::remove(const CIMName& className,
530 InheritanceTree &parentTree,
531 NameSpace *tag)
|
532 mike 1.16 {
533 // -- Lookup the node:
534
535 InheritanceTreeNode* node = 0;
536
|
537 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
538 throw PEGASUS_CIM_EXCEPTION
539 (CIM_ERR_INVALID_CLASS, className.getString());
|
540 mike 1.16
541 // -- Disallow if is has any subclasses:
542
543 if (node->subClasses)
|
544 kumpf 1.22 throw PEGASUS_CIM_EXCEPTION
545 (CIM_ERR_CLASS_HAS_CHILDREN, className.getString());
|
546 mike 1.16
547 // -- Remove as child of superclass:
548
549 InheritanceTreeNode* superClass = node->superClass;
550
|
551 schuur 1.25 if (tag) {
552 InheritanceTreeNode* itn = 0;
553 if (parentTree._rep->table.lookup(className.getString(),itn)) {
554 if (itn->extension) {
555 for (int j=0,m=itn->extNodes->size(); j<m; j++) {
556 if ((*(itn->extNodes))[j]->tag==tag) {
557 itn->extNodes->remove(j);
558 break;
559 }
560 }
561 if (itn->extNodes->size()==0) {
562 delete itn->extNodes;
563 parentTree._rep->table.remove(className.getString());
564 }
565 }
566 }
567 else {
568 Boolean result = superClass->removeSubClass(node);
569 PEGASUS_ASSERT(result);
570 }
571 }
572 schuur 1.25
573 else if (superClass)
|
574 mike 1.16 {
575 Boolean result = superClass->removeSubClass(node);
576 PEGASUS_ASSERT(result);
577 }
578
|
579 schuur 1.25
|
580 mike 1.16 // -- Remove from the hash table and delete:
581
|
582 kumpf 1.22 Boolean result = _rep->table.remove(className.getString());
|
583 mike 1.16 PEGASUS_ASSERT(result);
584 delete node;
585 }
586
587 void InheritanceTree::print(PEGASUS_STD(ostream)& os) const
588 {
589 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
590 i.value()->print(os);
591 }
592
593 PEGASUS_NAMESPACE_END
|