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

File: [Pegasus] / pegasus / src / Pegasus / Common / Attic / CIMPredicate.cpp (download)
Revision: 1.6, Thu Sep 12 16:27:01 2002 UTC (21 years, 9 months ago) by kumpf
Branch: MAIN
CVS Tags: test, pep_88, mday-merge-start, mday-merge-pegasus/src/Pegasus/Server, mday-merge-pegasus/src/Pegasus/Common, mday-2-0-patches, VERSION_2_1_RELEASE_HEAD, VERSION_2_1_RELEASE_BRANCH, VERSION_2_1_RELEASE, VERSION_2_1_1_RELEASE, TEST, STABLE, RELEASE_2_3_0-msg-freeze, RELEASE_2_2_1-snapshot, RELEASE_2_2_0_0-release, RELEASE_2_2_0-root, RELEASE_2_2_0-branch, RELEASE_2_2-root, PRE_LICENSE_UPDATE_2003, PEGASUS_FC_VERSION_2_2, LOCAL_ASSOCPROV-ROOT, LOCAL_ASSOCPROV-BRANCH
Changes since 1.5: +11 -11 lines
HP-RK API Review: Rename KeyBinding to CIMKeyBinding.  Remove definition of KeyBindingArray.

//%/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
// The Open Group, Tivoli Systems
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//==============================================================================
//
// Author: Mike Day (mdday@us.ibm.com)
//
// Modified By:
//
//%/////////////////////////////////////////////////////////////////////////////

#include "CIMPredicate.h"

PEGASUS_NAMESPACE_BEGIN
extern int _Compare(const String& s1_, const String& s2_);
static void _BubbleSort(Array<Predicate>& x)
{
    Uint32 n = x.size();

    if (n < 2)
	return;

    for (Uint32 i = 0; i < n - 1; i++)
    {
	for (Uint32 j = 0; j < n - 1; j++)
	{
	    if (_Compare(x[j].getName(), x[j+1].getName()) > 0)
	    {
		Predicate t = x[j];
		x[j] = x[j+1];
		x[j+1] = t;
	    }
	}
    }
}

// evaluation 
//-----------------------------------------
// p_name p_op p_val, r_name r_val 
//-- --- translates to --------------------
// r_val p_op p_val
//----------------------------------------
//

static Boolean evaluate_string(String ref, ExpressionOperator op, String pred)
{

   switch(op) 
   {
      case EQUAL:
	 return(ref == pred);
      case NE:
	 return(ref != pred);
      case GT:
	 return(ref > pred);
      case GTE:
	 return(ref >= pred);
      case LT:
	 return(ref < pred);
      case LTE:
	 return(ref <= pred);
      case PRESENT:
	 if(ref.size()) 
	    return true;
      default:
	 break;
   }
   return false;
}

static Boolean evaluate_int(String ref, ExpressionOperator op, String pred)
{
   CString ref_c = ref.getCString();
   char *ref_string = ref_c;
   if(ref_string == NULL)
      return false;
   
   CString pred_c = pred.getCString();
   char *pred_string = pred_c;
   if (pred_string == NULL)
      return false;
   
   if(*ref_string == '+' || *ref_string == '-' || 
      *pred_string == '+' || *pred_string == '-')
   {
      Sint32 ref_val = strtol(ref_string, (char **)0, 0);
      Sint32 pred_val = strtol(pred_string, (char **)0, 0);
      switch(op) 
      {
	 case EQUAL:
	    return(ref == pred);
	 case NE:
	    return(ref != pred);
	 case GT:
	    return(ref > pred);
	 case GTE:
	    return(ref >= pred);
	 case LT:
	    return(ref < pred);
	 case LTE:
	    return(ref <= pred);
	 case PRESENT:
	    if(ref != 0)
	       return true;
	 default:
	    break;
      }
   }
   else
   {
      Uint32 ref_val = strtoul(ref_string, (char **)0, 0);
      Uint32 pred_val = strtoul(pred_string, (char **)0, 0);
      switch(op) 
      {
	 case EQUAL:
	    return(ref == pred);
	 case NE:
	    return(ref != pred);
	 case GT:
	    return(ref > pred);
	 case GTE:
	    return(ref >= pred);
	 case LT:
	    return(ref < pred);
	 case LTE:
	    return(ref <= pred);
	 case PRESENT:
	    if(ref != 0)
	       return true;
	 default:
	    break;
      }
   }
   return false;
}

static Boolean evaluate_bool(String ref, ExpressionOperator op, String pred)
{

   
   switch(op) 
   {
      case EQUAL:
	 return(String::equalNoCase(ref, pred));
      case NE:
	 if(true == String::equalNoCase(ref, pred))
	    return(false);
	 return(true);
      case GT:
      case GTE:
      case LT:
      case LTE:
      case PRESENT:
      default:
	 break;
   }
   return false;
}

Predicate::Predicate(void) : CIMKeyBinding() { }

Predicate::Predicate(const Predicate& x) 
   : CIMKeyBinding(x), _op(x._op), _truth_value(x._truth_value) { }

Predicate::Predicate(const CIMKeyBinding& x, ExpressionOperator op = EQUAL, Boolean truth = true)
{
   if(this != &x)
   {
      CIMKeyBinding::operator=(x);
      _op = op;
      _truth_value = truth;
   }
   
}

Predicate::Predicate(const String& name, 
		     const String& value, 
		     Type type,
		     ExpressionOperator op = EQUAL,
		     Boolean truth = true) 
   : CIMKeyBinding(name, value, type), _op(op), _truth_value(truth) { }

Predicate::~Predicate() { }

Predicate& Predicate::operator=(const Predicate& x)
{
   if(this != &x)
   {
      CIMKeyBinding::operator=(x);
      _op = x._op;
      _truth_value = x._truth_value;
   }
   return *this;
}

Boolean  Predicate::evaluate(const CIMKeyBinding& key)
{
   _truth_value = false;
   if(true == CIMName::equal(this->getName() , key.getName()))
   { 
      Type type;
      if((type = this->getType()) == key.getType())
      {
	 switch(type)
	 {
	    case BOOLEAN:
	       _truth_value = evaluate_bool(key.getValue(), _op, this->getValue());
	       break;
	    case STRING:
	       _truth_value = evaluate_string(key.getValue(), _op, this->getValue());
	       break;
	    case NUMERIC:
	       _truth_value = evaluate_int(key.getValue(), _op, this->getValue());
	       break;
	    default:
	       break;
	 }
      }
   }
   return _truth_value;
}


//-----------------------------------------------------------------
// PredicateReference class implementation
//-----------------------------------------------------------------

PredicateReference::PredicateReference() 
   : CIMObjectPath(), _truth_value(false), 
     _logical_op(AND), _predicates() { }

PredicateReference::PredicateReference(const CIMObjectPath& x)
   : CIMObjectPath(x), _truth_value(false), 
     _logical_op(AND), _predicates() { }

PredicateReference::PredicateReference(const PredicateReference& x)
   : CIMObjectPath(x), _truth_value(x._truth_value),
     _logical_op(x._logical_op), _predicates(x._predicates)
{
   _BubbleSort(_predicates);
}

PredicateReference::PredicateReference(const String& objectName)
   :CIMObjectPath(objectName), _truth_value(false), 
    _logical_op(AND), _predicates() { }

PredicateReference::PredicateReference(const char *objectName)
   :CIMObjectPath(objectName), _truth_value(false), 
    _logical_op(AND), _predicates() { }

PredicateArray PredicateReference::getPredicateArray()
{
   return PredicateArray();
}

PredicateReference::PredicateReference(
	 const String& host,
	 const String& nameSpace,
	 const String& className,
	 const Array<CIMKeyBinding>& keyBindings,
	 const PredicateArray& predicates,
	 Boolean truth ,
	 LogicalOperator lop )
   : CIMObjectPath(host, nameSpace, className, keyBindings),
    _truth_value(true), _logical_op(lop)
{
   setPredicates(predicates);
}

PredicateReference::~PredicateReference() 
{

}
      
PredicateReference& PredicateReference::operator=(const PredicateReference& x)
{
   if(&x != this) 
   {
      CIMObjectPath::operator=(x);
      _truth_value = x._truth_value;
      _logical_op = x._logical_op;
      _predicates = x._predicates;
   }
   return *this;
}

PredicateReference& PredicateReference::operator=(const CIMObjectPath& x)
{
   if(&x != this)
   {
      CIMObjectPath::operator=(x);
      _truth_value = true;
      _logical_op = AND;
      _predicates =  PredicateArray();
   }
   return *this;
}

void PredicateReference::clear()
{
   CIMObjectPath::clear();
   _truth_value = true;
   _logical_op = AND;
   _predicates.clear();
}
      
void PredicateReference::set(
   const String& host,
   const String& nameSpace,
   const String& className,
   const Array<CIMKeyBinding>& keyBindings,
   const PredicateArray& predicates,
   Boolean truth ,
   LogicalOperator lop )
{
   CIMObjectPath::set(host, nameSpace, className, keyBindings);
   _truth_value = truth;
   _logical_op = lop;
   setPredicates(predicates);
}

void PredicateReference::setPredicates(const Array<Predicate>& predicates)
{
   _predicates = predicates;
   _BubbleSort(_predicates);
}

Boolean PredicateReference::identical(const CIMObjectPath& x) const
{
   return
      String::equal(getHost(), x.getHost()) &&
      String::equal(getNameSpace(), x.getNameSpace()) &&
      CIMName::equal(getClassName(), x.getClassName());
   
}

Boolean PredicateReference::identical(const PredicateReference& x) const
{
   return
      _truth_value == x._truth_value &&
      _logical_op == x._logical_op &&
      CIMObjectPath::identical(x) &&
      _predicates == x._predicates;
}

Boolean PredicateReference::evaluate(void)
{
   _truth_value = false;
   
   const Array<CIMKeyBinding>& keys = CIMObjectPath::getKeyBindings();
   int x = _predicates.size();
   int y = keys.size();
   int i, j;
   
   for( i = 0; i < x; i++)
   {
      Predicate& pred = _predicates[i];
      for ( j = 0; j < y; j++ ) 
      {
	 const CIMKeyBinding& key = keys[i];
	 if(pred == key)
	 {
	    if(true == pred.evaluate(key))
	    {
	       switch(_logical_op)
	       {
		  case AND:
		     _truth_value = true;
		     j = y; // force an exit from the loop
		     break;
		  case OR:
		     _truth_value = true;
		     return true;
		  case NOT:
		  default:
		     _truth_value = false;
		     return false;
	       }
	    }
	    else 
	    {
	       switch(_logical_op)
	       {
		  case AND:
		     _truth_value = false;
		     return false;
		  case OR:
		     break;
		  case NOT:
		     _truth_value = true;
		     break;
		  default:
		     _truth_value = false;
		     return false;
	       }
	    }
	 }
      }
   }
   return _truth_value;
}


PredicateTree::PredicateTree(void)
   : _truth_value(true), _logical_op(AND),
      _children(true), _pred(NULL) { }

PredicateTree::~PredicateTree(void)
{
   _children.empty_list();
   
   delete _pred;
}

PredicateTree::PredicateTree(const PredicateReference& pred)
   : _truth_value(true), _logical_op(AND),
     _children(true)
{
   _pred = new PredicateReference(pred);
}

PredicateTree::PredicateTree(PredicateReference* pred)
   : _truth_value(true), _logical_op(AND),
     _children(true)
{
   _pred = pred;
}

Boolean PredicateTree::evaluate(void) throw(IPCException)
{
   if(_pred != NULL)
   {
      Boolean truth =  _pred->evaluate();
      switch(_logical_op)
      {
	 case AND:
	    if(truth == false)
	    {
	       _truth_value = false;
	       return _truth_value;
	    }
	    else
	       _truth_value = true;
	    break;
	 case OR:
	    if(truth == true)
	    {
	       _truth_value = true;
	       return _truth_value;
	    }
	    else
	       _truth_value = false;
	    break;
	 case NOT:
	    if(truth == true)
	    {
	       _truth_value = false;
	       return _truth_value;
	    }
	    else
	       _truth_value = true;
	    break;
	 default:
	    _truth_value = true;
	    break;
      }
   }
   else 
      _truth_value = true;

   if(_children.count())
   {
      PredicateTree *children = NULL;
      // rw lock may be more appropriate
      // this call will throw an IPC exception
      _children.lock();
      
      while( NULL != ( children = _children.next(children)))
      {
	 Boolean truth = children->evaluate();
	 switch(_logical_op)
	 {
	    case AND:
	       if(truth == false )
	       {
		  _truth_value = false;
		  _children.unlock();
		  return _truth_value;
	       }
	       break;
	    case OR:
	       if(truth == true)
	       {
		  _truth_value = true;
		  _children.unlock();
		  return _truth_value;
	       }
	       else
		  _truth_value = false;
	       break;
	    case NOT:
	       if(truth == true)
	       {
		  _truth_value = false;
		  _children.unlock();
		  return _truth_value;
	       }
	       break;
	    default:
	       break;
	 }
      }
      _children.unlock();
   }
   return _truth_value;
}


PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2