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 karl 1.38 //
|
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 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/Common/String.h>
35 #include <Pegasus/Common/HashTable.h>
36 #include <Pegasus/Common/Dir.h>
|
37 chuck 1.24 #include <Pegasus/Common/CommonUTF.h>
|
38 r.kieninger 1.33 #include <Pegasus/Common/CIMNameUnchecked.h>
|
39 mike 1.16 #include "InheritanceTree.h"
40
|
41 schuur 1.25 #if 0
42 #undef PEG_METHOD_ENTER
43 #undef PEG_METHOD_EXIT
44 #define PEG_METHOD_ENTER(x,y) cout<<"--- Enter: "<<y<<endl;
45 #define PEG_METHOD_EXIT()
46 #endif
47
|
48 mike 1.16 PEGASUS_NAMESPACE_BEGIN
49
50 PEGASUS_USING_STD;
51
52 ////////////////////////////////////////////////////////////////////////////////
53 //
54 // NoCaseEqualFunc
55 //
56 ////////////////////////////////////////////////////////////////////////////////
57
58 struct NoCaseEqualFunc
59 {
60 static Boolean equal(const String& x, const String& y)
61 {
62 return String::equalNoCase(x, y);
63 }
64 };
65
66 ////////////////////////////////////////////////////////////////////////////////
67 //
|
68 schuur 1.25 // InheritanceTreeRep
69 //
70 ////////////////////////////////////////////////////////////////////////////////
71
|
72 marek 1.26 struct InheritanceTreeNode;
|
73 schuur 1.25
74 struct InheritanceTreeRep
75 {
|
76 mike 1.32 typedef HashTable<
|
77 kumpf 1.37 String, InheritanceTreeNode*, NoCaseEqualFunc, HashLowerCaseFunc> Table;
|
78 schuur 1.25 Table table;
|
79 mike 1.32
80 // Tradeoff: chosing a larger value decreases hash lookup time but
81 // increases iteration (which seems to be the dominant operations).
82 // This power of two (256) seems to produce the best results.
83
84 InheritanceTreeRep() : table(256)
85 {
86 }
|
87 schuur 1.25 };
88
89 ////////////////////////////////////////////////////////////////////////////////
90 //
|
91 mike 1.16 // InheritanceTreeNode
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94
|
95 schuur 1.25 class NameSpace;
96
97 struct InheritanceTreeExt
98 {
99 InheritanceTreeExt(NameSpace* t, InheritanceTreeNode* itn)
100 : tag(t), node(itn) {}
101 NameSpace* tag;
102 InheritanceTreeNode* node;
103 };
104
105
|
106 mike 1.16 struct InheritanceTreeNode
107 {
|
108 kumpf 1.22 InheritanceTreeNode(const CIMName& className);
|
109 venkat.puvvada 1.39 ~InheritanceTreeNode();
|
110 mike 1.16
111 void addSubClass(InheritanceTreeNode* subClass);
112
113 Boolean removeSubClass(InheritanceTreeNode* subClass);
114
115 void getSubClassNames(
|
116 kumpf 1.37 Array<CIMName>& subClassNames,
117 Boolean deepInheritance,
118 NameSpace* tag = 0);
|
119 mike 1.16
|
120 kumpf 1.22 void getSuperClassNames(Array<CIMName>& superClassNames);
|
121 mike 1.16
122 void print(PEGASUS_STD(ostream)& os) const;
|
123 schuur 1.25 #if 0
|
124 kumpf 1.22 Boolean isSubClass(const CIMName& className) const;
|
125 schuur 1.25 #endif
|
126 kumpf 1.22 CIMName className;
|
127 mike 1.16 InheritanceTreeNode* superClass;
128 InheritanceTreeNode* sibling;
|
129 schuur 1.25 union {
|
130 mike 1.16 InheritanceTreeNode* subClasses;
|
131 schuur 1.25 Array<InheritanceTreeExt*>* extNodes;
132 };
|
133 mike 1.16 Boolean provisional;
|
134 schuur 1.25 Boolean extension;
|
135 mike 1.16 };
136
|
137 kumpf 1.37 InheritanceTreeNode::InheritanceTreeNode(const CIMName& className)
138 : className(className), superClass(0),
|
139 schuur 1.25 sibling(0), subClasses(0), provisional(true), extension(false)
|
140 mike 1.16 {
141 }
142
|
143 venkat.puvvada 1.39 InheritanceTreeNode::~InheritanceTreeNode()
144 {
145 if (extension)
146 {
147 for(Uint32 i = 0, size = extNodes->size(); i < size; i++)
148 {
149 delete (*extNodes)[i];
150 }
151 delete extNodes;
152 }
153 }
154
|
155 mike 1.16 void InheritanceTreeNode::addSubClass(InheritanceTreeNode* subClass)
156 {
157 subClass->superClass = this;
158 subClass->sibling = subClasses;
159 subClasses = subClass;
160 }
161
162 Boolean InheritanceTreeNode::removeSubClass(InheritanceTreeNode* subClass)
163 {
164 InheritanceTreeNode* prev = 0;
165
166 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
167 {
|
168 kumpf 1.37 if (p == subClass)
169 {
170 if (prev)
171 prev->sibling = subClass->sibling;
172 else
173 subClasses = subClass->sibling;
174
175 return true;
176 }
177 prev = p;
|
178 mike 1.16 }
179
180 return false;
181 }
182
183 void InheritanceTreeNode::getSubClassNames(
|
184 schuur 1.25 Array<CIMName>& subClassNames,
185 Boolean deepInheritance,
|
186 kumpf 1.37 NameSpace* ns)
|
187 mike 1.16 {
188 // For each subClass:
189
|
190 kumpf 1.37 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
191 {
192 if (p->extension)
193 {
194 for (int j = 0, m = p->extNodes->size(); j < m; j++)
195 {
196 InheritanceTreeExt* itx = (*(p->extNodes))[j];
197 subClassNames.append(p->className);
198 if (!ns)
199 {
200 InheritanceTreeNode* itn=itx->node;
201 itn->getSubClassNames(subClassNames, deepInheritance, ns);
202 }
203 else if (itx->tag == ns)
204 {
205 InheritanceTreeNode* itn=itx->node;
206 itn->getSubClassNames(subClassNames, deepInheritance, ns);
207 break;
208 }
209 }
210 }
211 kumpf 1.37 else
212 {
213 subClassNames.append(p->className);
214 if (deepInheritance)
215 {
216 p->getSubClassNames(subClassNames, true, ns);
217 }
218 }
|
219 mike 1.16 }
220 }
221
|
222 schuur 1.25 #if 0
|
223 kumpf 1.22 Boolean InheritanceTreeNode::isSubClass(const CIMName& className_) const
|
224 mike 1.16 {
|
225 kumpf 1.22 if (className.equal (className_))
|
226 kumpf 1.37 return true;
|
227 mike 1.16
228 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
229 {
|
230 kumpf 1.37 if (p->className.equal (className_))
231 return true;
|
232 mike 1.16 }
233
234 return false;
235 }
|
236 schuur 1.25 #endif
|
237 mike 1.16
|
238 kumpf 1.22 void InheritanceTreeNode::getSuperClassNames(Array<CIMName>& superClassNames)
|
239 mike 1.16 {
240 // For each superClass:
241
242 for (InheritanceTreeNode* p = superClass; p; p = p->superClass)
243 {
|
244 kumpf 1.37 superClassNames.append(p->className);
245 // p->getSuperClassNames(superClassNames);
|
246 mike 1.16 }
247 }
248
249 void InheritanceTreeNode::print(PEGASUS_STD(ostream)& os) const
250 {
|
251 kumpf 1.40 os << className.getString() << " : " ;
252 os << (superClass ? superClass->className : CIMName()).getString();
|
253 mike 1.16
254 os << " { ";
255
256 for (InheritanceTreeNode* p = subClasses; p; p = p->sibling)
|
257 kumpf 1.40 os << p->className.getString() << ' ';
|
258 mike 1.16
259 os << "}" << endl;
260 }
261
262 ////////////////////////////////////////////////////////////////////////////////
263 //
264 // InheritanceTree
265 //
266 ////////////////////////////////////////////////////////////////////////////////
267
268 InheritanceTree::InheritanceTree()
269 {
270 _rep = new InheritanceTreeRep;
271 }
272
273 InheritanceTree::~InheritanceTree()
274 {
|
275 sage 1.18 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
276 delete i.value();
277
|
278 mike 1.16 delete _rep;
279 }
|
280 schuur 1.25 void InheritanceTree::insert(
281 const String& className,
282 const String& superClassName,
283 InheritanceTree& parentTree,
|
284 kumpf 1.37 NameSpace* tag)
|
285 schuur 1.25 {
286 InheritanceTreeNode* superClassNode = 0;
287
|
288 kumpf 1.37 if (superClassName.size() &&
289 !parentTree._rep->table.lookup(superClassName, superClassNode))
290 {
291 superClassNode =
292 new InheritanceTreeNode(CIMNameUnchecked(superClassName));
293 parentTree._rep->table.insert(superClassName, superClassNode);
|
294 schuur 1.25 }
295
296 InheritanceTreeNode* extNode = 0;
297
|
298 kumpf 1.37 if (!parentTree._rep->table.lookup(className, extNode))
299 {
300 extNode = new InheritanceTreeNode(CIMNameUnchecked(className));
301 parentTree._rep->table.insert(className, extNode);
302 extNode->extension=true;
303 extNode->extNodes=new Array<InheritanceTreeExt*>;
|
304 schuur 1.25 }
305
306 extNode->provisional = false;
307
308 if (superClassNode)
|
309 kumpf 1.37 superClassNode->addSubClass(extNode);
|
310 schuur 1.25
311 InheritanceTreeNode* classNode = 0;
312
|
313 kumpf 1.37 if (!_rep->table.lookup(className, classNode))
314 {
315 classNode = new InheritanceTreeNode(className);
316 _rep->table.insert(className, classNode);
|
317 schuur 1.25 }
318
319 extNode->extNodes->append(new InheritanceTreeExt(tag,classNode));
320
321 classNode->superClass = superClassNode;
322 }
|
323 mike 1.16
324 void InheritanceTree::insert(
|
325 kumpf 1.37 const String& className,
|
326 mike 1.16 const String& superClassName)
327 {
328 // ATTN: need found flag!
329
330 // -- Insert superclass:
331
332 InheritanceTreeNode* superClassNode = 0;
333
|
334 kumpf 1.37 if (superClassName.size() &&
335 !_rep->table.lookup(superClassName, superClassNode))
|
336 mike 1.16 {
|
337 kumpf 1.37 superClassNode =
338 new InheritanceTreeNode(CIMNameUnchecked(superClassName));
339 _rep->table.insert(superClassName, superClassNode);
|
340 mike 1.16 }
341
342 // -- Insert class:
|
343 kumpf 1.37
|
344 mike 1.16 InheritanceTreeNode* classNode = 0;
345
346 if (!_rep->table.lookup(className, classNode))
347 {
|
348 kumpf 1.37 classNode = new InheritanceTreeNode(CIMNameUnchecked(className));
349 _rep->table.insert(className, classNode);
|
350 mike 1.16 }
351
352 classNode->provisional = false;
353
354 // -- Link the class and superclass nodes:
355
356 if (superClassNode)
|
357 kumpf 1.37 superClassNode->addSubClass(classNode);
|
358 mike 1.16 }
359
|
360 schuur 1.25 void InheritanceTree::insertFromPath(const String& path,
361 InheritanceTree* parentTree,
|
362 kumpf 1.37 NameSpace* ns)
|
363 mike 1.16 {
364 for (Dir dir(path); dir.more(); dir.next())
365 {
|
366 kumpf 1.37 String fileName = dir.getName();
|
367 mike 1.16
|
368 kumpf 1.37 // Ignore the current and parent directories.
|
369 mike 1.16
|
370 kumpf 1.37 if (fileName == "." || fileName == "..")
371 continue;
|
372 mike 1.16
|
373 kumpf 1.37 Uint32 dot = fileName.find('.');
|
374 mike 1.16
|
375 kumpf 1.37 // Ignore files without dots in them:
|
376 mike 1.16
|
377 kumpf 1.37 if (dot == PEG_NOT_FOUND)
378 continue;
|
379 mike 1.16
|
380 kumpf 1.37 String className = fileName.subString(0, dot);
381 String superClassName = fileName.subString(dot + 1);
|
382 mike 1.16
|
383 kumpf 1.37 if (superClassName == "#")
384 superClassName.clear();
|
385 mike 1.16
|
386 bafna.mukesh 1.28
|
387 chuck 1.24 #ifdef PEGASUS_REPOSITORY_ESCAPE_UTF8
|
388 kumpf 1.37 if (ns)
389 insert(
390 escapeStringDecoder(className),
391 escapeStringDecoder(superClassName),
392 *parentTree, ns);
393 else
394 insert(
395 escapeStringDecoder(className),
396 escapeStringDecoder(superClassName));
|
397 chuck 1.24 #else
|
398 kumpf 1.37 if (ns)
399 insert(className, superClassName, *parentTree, ns);
400 else
401 insert(className, superClassName);
|
402 chuck 1.24 #endif
|
403 mike 1.16 }
404 }
405
406 void InheritanceTree::check() const
407 {
408 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
409 {
|
410 kumpf 1.37 if (i.value()->provisional)
411 throw InvalidInheritanceTree(i.value()->className.getString());
|
412 mike 1.16 }
413 }
414
415 Boolean InheritanceTree::getSubClassNames(
|
416 kumpf 1.22 const CIMName& className,
|
417 mike 1.16 Boolean deepInheritance,
|
418 schuur 1.25 Array<CIMName>& subClassNames,
|
419 kumpf 1.37 NameSpace* ns) const
|
420 mike 1.16 {
|
421 kumpf 1.37 // -- Case 1: className is empty: get all class names (if deepInheritance)
422 // -- or just root class names (if not deepInheritance).
|
423 mike 1.16
|
424 kumpf 1.37 if (className.isNull())
425 {
426 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start();i;i++)
427 {
428 InheritanceTreeNode* itn=i.value();
429 if (itn->extension)
430 {
431 if (!ns)
432 continue;
433 for (int j=0,m=itn->extNodes->size(); j<m; j++)
434 {
435 InheritanceTreeExt* itx=(*(itn->extNodes))[j];
436 if (itx->tag==ns)
437 {
438 InheritanceTreeNode* itn=itx->node;
439 if (deepInheritance)
440 {
441 subClassNames.append(CIMNameUnchecked(i.key()));
442 itn->getSubClassNames(
443 subClassNames, deepInheritance, ns);
444 }
445 kumpf 1.37 else if (!i.value()->superClass)
446 subClassNames.append(CIMNameUnchecked(i.key()));
447 break;
448 }
449 }
450 }
451 else if (deepInheritance)
452 {
453 // Append all classes:
454 subClassNames.append(CIMNameUnchecked(i.key()));
455 }
456 else if (!i.value()->superClass)
457 {
458 // Just append root classes:
459 subClassNames.append(CIMNameUnchecked(i.key()));
460 }
461 }
462 return true;
463 }
|
464 schuur 1.25
|
465 kumpf 1.37 // -- Case 2: className non-empty: get names of classes descendent from
466 // -- the given class.
|
467 schuur 1.25
|
468 kumpf 1.37 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
469 {
470 if (className.equal (CIMNameUnchecked(i.key())))
471 {
472 i.value()->getSubClassNames(subClassNames, deepInheritance, ns);
473 return true;
474 }
475 }
|
476 schuur 1.25
|
477 kumpf 1.37 // Not found!
478 return false;
|
479 mike 1.16 }
|
480 kumpf 1.37
|
481 schuur 1.25 #if 0
|
482 mike 1.17 Boolean InheritanceTree::isSubClass(
|
483 kumpf 1.37 const CIMName& class1,
|
484 kumpf 1.22 const CIMName& class2) const
|
485 mike 1.16 {
|
486 kumpf 1.37 InheritanceTreeNode* node = 0;
|
487 mike 1.16
|
488 kumpf 1.22 if (!_rep->table.lookup(class1.getString(), node))
|
489 kumpf 1.37 return false;
|
490 mike 1.16
|
491 kumpf 1.22 return node->isSubClass(class2.getString());
|
492 mike 1.16 }
|
493 schuur 1.25 #endif
|
494 mike 1.16
495 Boolean InheritanceTree::getSuperClassNames(
|
496 kumpf 1.22 const CIMName& className,
497 Array<CIMName>& superClassNames) const
|
498 mike 1.16 {
499 InheritanceTreeNode* classNode;
500
|
501 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
502 mike 1.16 {
|
503 kumpf 1.37 classNode->getSuperClassNames(superClassNames);
504 return true;
|
505 mike 1.16 }
506
507 return false;
508 }
509
510 Boolean InheritanceTree::getSuperClass(
|
511 kumpf 1.22 const CIMName& className,
512 CIMName& superClassName) const
|
513 mike 1.16 {
514 InheritanceTreeNode* classNode;
515
|
516 kumpf 1.22 if (_rep->table.lookup(className.getString(), classNode))
|
517 mike 1.16 {
|
518 kumpf 1.37 if (classNode->superClass)
519 {
520 superClassName = classNode->superClass->className;
521 }
522 else
523 {
524 superClassName.clear();
525 }
|
526 mike 1.16
|
527 kumpf 1.37 return true;
|
528 mike 1.16 }
529
530 return false;
531 }
532
533 Boolean InheritanceTree::hasSubClasses(
|
534 kumpf 1.22 const CIMName& className,
|
535 mike 1.16 Boolean& hasSubClasses) const
536 {
|
537 kumpf 1.37 InheritanceTreeNode* node = 0;
|
538 mike 1.16
|
539 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
|
540 kumpf 1.37 return false;
|
541 mike 1.16
542 hasSubClasses = node->subClasses != 0;
543 return true;
544 }
545
|
546 kumpf 1.22 Boolean InheritanceTree::containsClass(const CIMName& className) const
|
547 mike 1.16 {
|
548 kumpf 1.22 return _rep->table.contains(className.getString());
|
549 mike 1.16 }
550
|
551 kumpf 1.37 void InheritanceTree::remove(
552 const CIMName& className,
553 InheritanceTree& parentTree,
554 NameSpace* tag)
|
555 mike 1.16 {
556 // -- Lookup the node:
557
|
558 kumpf 1.37 InheritanceTreeNode* node = 0;
|
559 mike 1.16
|
560 kumpf 1.22 if (!_rep->table.lookup(className.getString(), node))
|
561 kumpf 1.37 throw PEGASUS_CIM_EXCEPTION(
562 CIM_ERR_INVALID_CLASS, className.getString());
|
563 mike 1.16
564 // -- Disallow if is has any subclasses:
565
566 if (node->subClasses)
|
567 kumpf 1.37 throw PEGASUS_CIM_EXCEPTION(
568 CIM_ERR_CLASS_HAS_CHILDREN, className.getString());
|
569 mike 1.16
570 // -- Remove as child of superclass:
571
572 InheritanceTreeNode* superClass = node->superClass;
573
|
574 kumpf 1.37 if (tag)
575 {
576 InheritanceTreeNode* itn = 0;
577 if (parentTree._rep->table.lookup(className.getString(), itn))
578 {
579 if (itn->extension)
580 {
581 for (int j = 0, m = itn->extNodes->size(); j < m; j++)
582 {
583 if ((*(itn->extNodes))[j]->tag == tag)
584 {
585 itn->extNodes->remove(j);
586 break;
587 }
588 }
589 if (itn->extNodes->size() == 0)
590 {
591 delete itn->extNodes;
592 parentTree._rep->table.remove(className.getString());
|
593 schuur 1.25 }
|
594 kumpf 1.37 }
595 }
596 else
597 {
598 Boolean result = superClass->removeSubClass(node);
599 PEGASUS_ASSERT(result);
600 }
|
601 schuur 1.25 }
602 else if (superClass)
|
603 mike 1.16 {
|
604 kumpf 1.37 Boolean result = superClass->removeSubClass(node);
605 PEGASUS_ASSERT(result);
|
606 mike 1.16 }
607
|
608 schuur 1.25
|
609 mike 1.16 // -- Remove from the hash table and delete:
610
|
611 kumpf 1.22 Boolean result = _rep->table.remove(className.getString());
|
612 mike 1.16 PEGASUS_ASSERT(result);
613 delete node;
614 }
615
616 void InheritanceTree::print(PEGASUS_STD(ostream)& os) const
617 {
618 for (InheritanceTreeRep::Table::Iterator i = _rep->table.start(); i; i++)
|
619 kumpf 1.37 i.value()->print(os);
|
620 mike 1.16 }
621
622 PEGASUS_NAMESPACE_END
|