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

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2