(file) Return to InheritanceTree.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2