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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2