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

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.4 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4           // The Open Group, Tivoli Systems
  5 mike  1.2 //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // of this software and associated documentation files (the "Software"), to
  8           // deal in the Software without restriction, including without limitation the
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10           // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12 kumpf 1.4 // 
 13 mike  1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22           //==============================================================================
 23           //
 24           // Author: Mike Day (mdday@us.ibm.com)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           #include "CIMPredicate.h"
 31           
 32           PEGASUS_NAMESPACE_BEGIN
 33           extern int _Compare(const String& s1_, const String& s2_);
 34 mike  1.2 static void _BubbleSort(Array<Predicate>& x)
 35           {
 36               Uint32 n = x.size();
 37           
 38               if (n < 2)
 39           	return;
 40           
 41               for (Uint32 i = 0; i < n - 1; i++)
 42               {
 43           	for (Uint32 j = 0; j < n - 1; j++)
 44           	{
 45           	    if (_Compare(x[j].getName(), x[j+1].getName()) > 0)
 46           	    {
 47           		Predicate t = x[j];
 48           		x[j] = x[j+1];
 49           		x[j+1] = t;
 50           	    }
 51           	}
 52               }
 53           }
 54           
 55 mike  1.2 // evaluation 
 56           //-----------------------------------------
 57           // p_name p_op p_val, r_name r_val 
 58           //-- --- translates to --------------------
 59           // r_val p_op p_val
 60           //----------------------------------------
 61           //
 62           
 63           static Boolean evaluate_string(String ref, ExpressionOperator op, String pred)
 64           {
 65           
 66              switch(op) 
 67              {
 68                 case EQUAL:
 69           	 return(ref == pred);
 70                 case NE:
 71           	 return(ref != pred);
 72                 case GT:
 73           	 return(ref > pred);
 74                 case GTE:
 75           	 return(ref >= pred);
 76 mike  1.2       case LT:
 77           	 return(ref < pred);
 78                 case LTE:
 79           	 return(ref <= pred);
 80                 case PRESENT:
 81           	 if(ref.size()) 
 82           	    return true;
 83                 default:
 84           	 break;
 85              }
 86              return false;
 87           }
 88           
 89           static Boolean evaluate_int(String ref, ExpressionOperator op, String pred)
 90           {
 91 kumpf 1.5    CString ref_c = ref.getCString();
 92              char *ref_string = ref_c;
 93 mike  1.2    if(ref_string == NULL)
 94                 return false;
 95              
 96 kumpf 1.5    CString pred_c = pred.getCString();
 97              char *pred_string = pred_c;
 98 mike  1.2    if (pred_string == NULL)
 99                 return false;
100              
101              if(*ref_string == '+' || *ref_string == '-' || 
102                 *pred_string == '+' || *pred_string == '-')
103              {
104                 Sint32 ref_val = strtol(ref_string, (char **)0, 0);
105                 Sint32 pred_val = strtol(pred_string, (char **)0, 0);
106                 switch(op) 
107                 {
108           	 case EQUAL:
109           	    return(ref == pred);
110           	 case NE:
111           	    return(ref != pred);
112           	 case GT:
113           	    return(ref > pred);
114           	 case GTE:
115           	    return(ref >= pred);
116           	 case LT:
117           	    return(ref < pred);
118           	 case LTE:
119 mike  1.2 	    return(ref <= pred);
120           	 case PRESENT:
121           	    if(ref != 0)
122           	       return true;
123           	 default:
124           	    break;
125                 }
126              }
127              else
128              {
129                 Uint32 ref_val = strtoul(ref_string, (char **)0, 0);
130                 Uint32 pred_val = strtoul(pred_string, (char **)0, 0);
131                 switch(op) 
132                 {
133           	 case EQUAL:
134           	    return(ref == pred);
135           	 case NE:
136           	    return(ref != pred);
137           	 case GT:
138           	    return(ref > pred);
139           	 case GTE:
140 mike  1.2 	    return(ref >= pred);
141           	 case LT:
142           	    return(ref < pred);
143           	 case LTE:
144           	    return(ref <= pred);
145           	 case PRESENT:
146           	    if(ref != 0)
147           	       return true;
148           	 default:
149           	    break;
150                 }
151              }
152              return false;
153           }
154           
155           static Boolean evaluate_bool(String ref, ExpressionOperator op, String pred)
156           {
157           
158              
159              switch(op) 
160              {
161 mike  1.2       case EQUAL:
162           	 return(String::equalNoCase(ref, pred));
163                 case NE:
164           	 if(true == String::equalNoCase(ref, pred))
165           	    return(false);
166           	 return(true);
167                 case GT:
168                 case GTE:
169                 case LT:
170                 case LTE:
171                 case PRESENT:
172                 default:
173           	 break;
174              }
175              return false;
176           }
177           
178 kumpf 1.6 Predicate::Predicate(void) : CIMKeyBinding() { }
179 mike  1.2 
180           Predicate::Predicate(const Predicate& x) 
181 kumpf 1.6    : CIMKeyBinding(x), _op(x._op), _truth_value(x._truth_value) { }
182 mike  1.2 
183 kumpf 1.6 Predicate::Predicate(const CIMKeyBinding& x, ExpressionOperator op = EQUAL, Boolean truth = true)
184 mike  1.2 {
185              if(this != &x)
186              {
187 kumpf 1.6       CIMKeyBinding::operator=(x);
188 mike  1.2       _op = op;
189                 _truth_value = truth;
190              }
191              
192           }
193           
194           Predicate::Predicate(const String& name, 
195           		     const String& value, 
196           		     Type type,
197           		     ExpressionOperator op = EQUAL,
198           		     Boolean truth = true) 
199 kumpf 1.6    : CIMKeyBinding(name, value, type), _op(op), _truth_value(truth) { }
200 mike  1.2 
201           Predicate::~Predicate() { }
202           
203           Predicate& Predicate::operator=(const Predicate& x)
204           {
205              if(this != &x)
206              {
207 kumpf 1.6       CIMKeyBinding::operator=(x);
208 mike  1.2       _op = x._op;
209                 _truth_value = x._truth_value;
210              }
211              return *this;
212           }
213           
214 kumpf 1.6 Boolean  Predicate::evaluate(const CIMKeyBinding& key)
215 mike  1.2 {
216              _truth_value = false;
217              if(true == CIMName::equal(this->getName() , key.getName()))
218              { 
219                 Type type;
220                 if((type = this->getType()) == key.getType())
221                 {
222           	 switch(type)
223           	 {
224           	    case BOOLEAN:
225           	       _truth_value = evaluate_bool(key.getValue(), _op, this->getValue());
226           	       break;
227           	    case STRING:
228           	       _truth_value = evaluate_string(key.getValue(), _op, this->getValue());
229           	       break;
230           	    case NUMERIC:
231           	       _truth_value = evaluate_int(key.getValue(), _op, this->getValue());
232           	       break;
233           	    default:
234           	       break;
235           	 }
236 mike  1.2       }
237              }
238              return _truth_value;
239           }
240           
241           
242           //-----------------------------------------------------------------
243           // PredicateReference class implementation
244           //-----------------------------------------------------------------
245           
246           PredicateReference::PredicateReference() 
247 kumpf 1.3    : CIMObjectPath(), _truth_value(false), 
248 mike  1.2      _logical_op(AND), _predicates() { }
249           
250 kumpf 1.3 PredicateReference::PredicateReference(const CIMObjectPath& x)
251              : CIMObjectPath(x), _truth_value(false), 
252 mike  1.2      _logical_op(AND), _predicates() { }
253           
254           PredicateReference::PredicateReference(const PredicateReference& x)
255 kumpf 1.3    : CIMObjectPath(x), _truth_value(x._truth_value),
256 mike  1.2      _logical_op(x._logical_op), _predicates(x._predicates)
257           {
258              _BubbleSort(_predicates);
259           }
260           
261           PredicateReference::PredicateReference(const String& objectName)
262 kumpf 1.3    :CIMObjectPath(objectName), _truth_value(false), 
263 mike  1.2     _logical_op(AND), _predicates() { }
264           
265           PredicateReference::PredicateReference(const char *objectName)
266 kumpf 1.3    :CIMObjectPath(objectName), _truth_value(false), 
267 mike  1.2     _logical_op(AND), _predicates() { }
268           
269           PredicateArray PredicateReference::getPredicateArray()
270           {
271              return PredicateArray();
272           }
273           
274           PredicateReference::PredicateReference(
275           	 const String& host,
276           	 const String& nameSpace,
277           	 const String& className,
278 kumpf 1.6 	 const Array<CIMKeyBinding>& keyBindings,
279 mike  1.2 	 const PredicateArray& predicates,
280           	 Boolean truth ,
281           	 LogicalOperator lop )
282 kumpf 1.3    : CIMObjectPath(host, nameSpace, className, keyBindings),
283 mike  1.2     _truth_value(true), _logical_op(lop)
284           {
285              setPredicates(predicates);
286           }
287           
288           PredicateReference::~PredicateReference() 
289           {
290           
291           }
292                 
293           PredicateReference& PredicateReference::operator=(const PredicateReference& x)
294           {
295              if(&x != this) 
296              {
297 kumpf 1.3       CIMObjectPath::operator=(x);
298 mike  1.2       _truth_value = x._truth_value;
299                 _logical_op = x._logical_op;
300                 _predicates = x._predicates;
301              }
302              return *this;
303           }
304           
305 kumpf 1.3 PredicateReference& PredicateReference::operator=(const CIMObjectPath& x)
306 mike  1.2 {
307              if(&x != this)
308              {
309 kumpf 1.3       CIMObjectPath::operator=(x);
310 mike  1.2       _truth_value = true;
311                 _logical_op = AND;
312                 _predicates =  PredicateArray();
313              }
314              return *this;
315           }
316           
317           void PredicateReference::clear()
318           {
319 kumpf 1.3    CIMObjectPath::clear();
320 mike  1.2    _truth_value = true;
321              _logical_op = AND;
322              _predicates.clear();
323           }
324                 
325           void PredicateReference::set(
326              const String& host,
327              const String& nameSpace,
328              const String& className,
329 kumpf 1.6    const Array<CIMKeyBinding>& keyBindings,
330 mike  1.2    const PredicateArray& predicates,
331              Boolean truth ,
332              LogicalOperator lop )
333           {
334 kumpf 1.3    CIMObjectPath::set(host, nameSpace, className, keyBindings);
335 mike  1.2    _truth_value = truth;
336              _logical_op = lop;
337              setPredicates(predicates);
338           }
339           
340           void PredicateReference::setPredicates(const Array<Predicate>& predicates)
341           {
342              _predicates = predicates;
343              _BubbleSort(_predicates);
344           }
345           
346 kumpf 1.3 Boolean PredicateReference::identical(const CIMObjectPath& x) const
347 mike  1.2 {
348              return
349                 String::equal(getHost(), x.getHost()) &&
350                 String::equal(getNameSpace(), x.getNameSpace()) &&
351                 CIMName::equal(getClassName(), x.getClassName());
352              
353           }
354           
355           Boolean PredicateReference::identical(const PredicateReference& x) const
356           {
357              return
358                 _truth_value == x._truth_value &&
359                 _logical_op == x._logical_op &&
360 kumpf 1.3       CIMObjectPath::identical(x) &&
361 mike  1.2       _predicates == x._predicates;
362           }
363           
364           Boolean PredicateReference::evaluate(void)
365           {
366              _truth_value = false;
367              
368 kumpf 1.6    const Array<CIMKeyBinding>& keys = CIMObjectPath::getKeyBindings();
369 mike  1.2    int x = _predicates.size();
370              int y = keys.size();
371              int i, j;
372              
373              for( i = 0; i < x; i++)
374              {
375                 Predicate& pred = _predicates[i];
376                 for ( j = 0; j < y; j++ ) 
377                 {
378 kumpf 1.6 	 const CIMKeyBinding& key = keys[i];
379 mike  1.2 	 if(pred == key)
380           	 {
381           	    if(true == pred.evaluate(key))
382           	    {
383           	       switch(_logical_op)
384           	       {
385           		  case AND:
386           		     _truth_value = true;
387           		     j = y; // force an exit from the loop
388           		     break;
389           		  case OR:
390           		     _truth_value = true;
391           		     return true;
392           		  case NOT:
393           		  default:
394           		     _truth_value = false;
395           		     return false;
396           	       }
397           	    }
398           	    else 
399           	    {
400 mike  1.2 	       switch(_logical_op)
401           	       {
402           		  case AND:
403           		     _truth_value = false;
404           		     return false;
405           		  case OR:
406           		     break;
407           		  case NOT:
408           		     _truth_value = true;
409           		     break;
410           		  default:
411           		     _truth_value = false;
412           		     return false;
413           	       }
414           	    }
415           	 }
416                 }
417              }
418              return _truth_value;
419           }
420           
421 mike  1.2 
422           PredicateTree::PredicateTree(void)
423              : _truth_value(true), _logical_op(AND),
424                 _children(true), _pred(NULL) { }
425           
426           PredicateTree::~PredicateTree(void)
427           {
428              _children.empty_list();
429              
430              delete _pred;
431           }
432           
433           PredicateTree::PredicateTree(const PredicateReference& pred)
434              : _truth_value(true), _logical_op(AND),
435                _children(true)
436           {
437              _pred = new PredicateReference(pred);
438           }
439           
440           PredicateTree::PredicateTree(PredicateReference* pred)
441              : _truth_value(true), _logical_op(AND),
442 mike  1.2      _children(true)
443           {
444              _pred = pred;
445           }
446           
447           Boolean PredicateTree::evaluate(void) throw(IPCException)
448           {
449              if(_pred != NULL)
450              {
451                 Boolean truth =  _pred->evaluate();
452                 switch(_logical_op)
453                 {
454           	 case AND:
455           	    if(truth == false)
456           	    {
457           	       _truth_value = false;
458           	       return _truth_value;
459           	    }
460           	    else
461           	       _truth_value = true;
462           	    break;
463 mike  1.2 	 case OR:
464           	    if(truth == true)
465           	    {
466           	       _truth_value = true;
467           	       return _truth_value;
468           	    }
469           	    else
470           	       _truth_value = false;
471           	    break;
472           	 case NOT:
473           	    if(truth == true)
474           	    {
475           	       _truth_value = false;
476           	       return _truth_value;
477           	    }
478           	    else
479           	       _truth_value = true;
480           	    break;
481           	 default:
482           	    _truth_value = true;
483           	    break;
484 mike  1.2       }
485              }
486              else 
487                 _truth_value = true;
488           
489              if(_children.count())
490              {
491                 PredicateTree *children = NULL;
492                 // rw lock may be more appropriate
493                 // this call will throw an IPC exception
494                 _children.lock();
495                 
496                 while( NULL != ( children = _children.next(children)))
497                 {
498           	 Boolean truth = children->evaluate();
499           	 switch(_logical_op)
500           	 {
501           	    case AND:
502           	       if(truth == false )
503           	       {
504           		  _truth_value = false;
505 mike  1.2 		  _children.unlock();
506           		  return _truth_value;
507           	       }
508           	       break;
509           	    case OR:
510           	       if(truth == true)
511           	       {
512           		  _truth_value = true;
513           		  _children.unlock();
514           		  return _truth_value;
515           	       }
516           	       else
517           		  _truth_value = false;
518           	       break;
519           	    case NOT:
520           	       if(truth == true)
521           	       {
522           		  _truth_value = false;
523           		  _children.unlock();
524           		  return _truth_value;
525           	       }
526 mike  1.2 	       break;
527           	    default:
528           	       break;
529           	 }
530                 }
531                 _children.unlock();
532              }
533              return _truth_value;
534           }
535           
536           
537           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2