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
|