Constraint_Visitors.cpp

Go to the documentation of this file.
00001 // $Id: Constraint_Visitors.cpp 78224 2007-04-26 19:09:06Z elliott_c $
00002 
00003 #include "orbsvcs/Trader/Constraint_Visitors.h"
00004 #include "orbsvcs/Trader/Constraint_Nodes.h"
00005 #include "orbsvcs/Trader/Interpreter_Utils_T.h"
00006 #include "orbsvcs/Trader/Constraint_Tokens.h"
00007 
00008 #include "tao/DynamicAny/DynSequence_i.h"
00009 
00010 #include "ace/OS_NS_string.h"
00011 
00012 
00013 ACE_RCSID (Trader,
00014            Constraint_Visitors,
00015            "$Id: Constraint_Visitors.cpp 78224 2007-04-26 19:09:06Z elliott_c $")
00016 
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 TAO_Constraint_Evaluator::Operand_Queue::Operand_Queue (void)
00021 {
00022 }
00023 
00024 TAO_Literal_Constraint&
00025 TAO_Constraint_Evaluator::Operand_Queue::get_left_operand (void)
00026 {
00027   TAO_Literal_Constraint* left_operand = 0;
00028   this->get (left_operand, 1);
00029   return *left_operand;
00030 }
00031 
00032 TAO_Literal_Constraint&
00033 TAO_Constraint_Evaluator::Operand_Queue::get_right_operand (void)
00034 {
00035   TAO_Literal_Constraint* right_operand = 0;
00036   this->get (right_operand);
00037   return *right_operand;
00038 }
00039 
00040 TAO_Literal_Constraint&
00041 TAO_Constraint_Evaluator::Operand_Queue::get_operand (void)
00042 {
00043   TAO_Literal_Constraint* operand = 0;
00044   this->get (operand);
00045   return *operand;
00046 }
00047 
00048 void
00049 TAO_Constraint_Evaluator::Operand_Queue::dequeue_operand (void)
00050 {
00051   TAO_Literal_Constraint operand;
00052   this->dequeue_head (operand);
00053 }
00054 
00055 TAO_Constraint_Evaluator::TAO_Constraint_Evaluator (void)
00056 {
00057   // No-Op.
00058 }
00059 
00060 CORBA::Boolean
00061 TAO_Constraint_Evaluator::evaluate_constraint (TAO_Constraint* root)
00062 {
00063   CORBA::Boolean result = 0;
00064   this->queue_.reset ();
00065 
00066   // Evaluate the offer according to the constraints in root_;
00067   if (root != 0)
00068     {
00069       if ((root->accept (this) == 0) &&
00070           (! this->queue_.is_empty ()))
00071         {
00072           result = (CORBA::Boolean) this->queue_.get_operand();
00073           this->queue_.dequeue_operand ();
00074         }
00075     }
00076 
00077   // If a property couldn't be evaluated we must return 0.
00078   return result;
00079 }
00080 
00081 int
00082 TAO_Constraint_Evaluator::
00083 evaluate_preference (TAO_Constraint* root,
00084                     TAO_Literal_Constraint& result)
00085 {
00086   int return_value = -1;
00087   while (! this->queue_.is_empty ())
00088     this->queue_.dequeue_operand ();
00089 
00090   // Evaluate the offer according to the constraints in root_;
00091   if (root != 0)
00092     {
00093       if ((root->accept (this) == 0) &&
00094           (! this->queue_.is_empty ()))
00095         {
00096           result = this->queue_.get_operand ();
00097           this->queue_.dequeue_operand ();
00098           return_value = 0;
00099         }
00100     }
00101 
00102   return return_value;
00103 }
00104 
00105 int
00106 TAO_Constraint_Evaluator::visit_constraint(TAO_Unary_Constraint* constraint)
00107 {
00108   TAO_Constraint* operand = constraint->operand ();
00109   return operand->accept (this);
00110 }
00111 
00112 int
00113 TAO_Constraint_Evaluator::visit_with (TAO_Unary_Constraint* unary_with)
00114 {
00115   TAO_Constraint* operand = unary_with->operand ();
00116   return operand->accept (this);
00117 }
00118 
00119 int
00120 TAO_Constraint_Evaluator::visit_min (TAO_Unary_Constraint* unary_min)
00121 {
00122   TAO_Constraint* operand = unary_min->operand ();
00123   return operand->accept (this);
00124 }
00125 
00126 int
00127 TAO_Constraint_Evaluator::visit_max (TAO_Unary_Constraint* unary_max)
00128 {
00129   TAO_Constraint* operand = unary_max->operand ();
00130   return operand->accept (this);
00131 }
00132 
00133 int
00134 TAO_Constraint_Evaluator::visit_random (TAO_Noop_Constraint *)
00135 {
00136   TAO_Literal_Constraint random (static_cast<CORBA::LongLong> (ACE_OS::rand ()));
00137   this->queue_.enqueue_head (random);
00138   return 0;
00139 }
00140 
00141 int
00142 TAO_Constraint_Evaluator::visit_first (TAO_Noop_Constraint *)
00143 {
00144   TAO_Literal_Constraint first (static_cast<CORBA::LongLong> (0));
00145   this->queue_.enqueue_head (first);
00146   return 0;
00147 }
00148 
00149 int
00150 TAO_Constraint_Evaluator::
00151 visit_and (TAO_Binary_Constraint* boolean_and)
00152 {
00153   int return_value = -1;
00154   CORBA::Boolean result = (CORBA::Boolean) 0;
00155   TAO_Constraint* left = boolean_and->left_operand (),
00156     *right = boolean_and->right_operand ();
00157 
00158   // Short circuiting AND.
00159 
00160   if (left->accept (this) == 0)
00161     {
00162       result = (CORBA::Boolean) this->queue_.get_operand ();
00163       this->queue_.dequeue_operand ();
00164 
00165       if (result)
00166         {
00167           if (right->accept(this) == 0)
00168             {
00169               result = (CORBA::Boolean) this->queue_.get_operand();
00170               this->queue_.dequeue_operand ();
00171 
00172               return_value = 0;
00173             }
00174         }
00175       else
00176         return_value = 0;
00177     }
00178 
00179   if (return_value != -1)
00180     this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00181 
00182   return return_value;
00183 }
00184 
00185 int
00186 TAO_Constraint_Evaluator::
00187 visit_or (TAO_Binary_Constraint* boolean_or)
00188 {
00189   int return_value = -1;
00190   CORBA::Boolean result = (CORBA::Boolean) 0;
00191   TAO_Constraint* left = boolean_or->left_operand (),
00192     *right = boolean_or->right_operand ();
00193 
00194   // Short-circuiting OR.
00195 
00196   if (left->accept (this) == 0)
00197     {
00198       result = (CORBA::Boolean) this->queue_.get_operand ();
00199       this->queue_.dequeue_operand ();
00200 
00201       if (result == (CORBA::Boolean) 0)
00202         {
00203           if (right->accept (this) == 0)
00204             {
00205               result = (CORBA::Boolean) this->queue_.get_operand ();
00206               this->queue_.dequeue_operand ();
00207               return_value = 0;
00208             }
00209         }
00210       else
00211         return_value = 0;
00212     }
00213 
00214   if (return_value != -1)
00215     this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00216 
00217   return return_value;
00218 }
00219 
00220 int
00221 TAO_Constraint_Evaluator::
00222 visit_not (TAO_Unary_Constraint* unary_not)
00223 {
00224   int return_value = -1;
00225   TAO_Constraint* operand = unary_not->operand ();
00226 
00227   // Logical NOT.
00228 
00229   if (operand->accept (this) == 0)
00230     {
00231       CORBA::Boolean result = ! (CORBA::Boolean)this->queue_.get_operand ();
00232       this->queue_.dequeue_operand ();
00233       this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00234 
00235       return_value = 0;
00236     }
00237 
00238   return return_value;
00239 }
00240 
00241 int
00242 TAO_Constraint_Evaluator::
00243 visit_exist (TAO_Unary_Constraint* unary_exist)
00244 {
00245   TAO_Property_Constraint* operand =
00246     (TAO_Property_Constraint*) unary_exist->operand ();
00247   CORBA::String_var property_name ((const char*) operand->name ());
00248 
00249   // Determine if a property is defined on this offer.
00250 
00251   CORBA::Boolean result =
00252     (CORBA::Boolean) (this->props_.find (property_name) == 0);
00253 
00254   this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00255   return 0;
00256 }
00257 
00258 int
00259 TAO_Constraint_Evaluator::
00260 visit_unary_minus (TAO_Unary_Constraint* unary_minus)
00261 {
00262   int return_value = -1;
00263   TAO_Constraint* operand = unary_minus->operand ();
00264 
00265   if (operand->accept (this) == 0)
00266     {
00267       TAO_Literal_Constraint result = - this->queue_.get_operand ();
00268       this->queue_.dequeue_operand ();
00269       this->queue_.enqueue_head (result);
00270 
00271       return_value = 0;
00272     }
00273 
00274   return return_value;
00275 }
00276 
00277 void
00278 TAO_Constraint_Evaluator::do_the_op (int operation)
00279 {
00280   TAO_Literal_Constraint& l_op = this->queue_.get_left_operand ();
00281   TAO_Literal_Constraint& r_op = this->queue_.get_right_operand ();
00282 
00283   // Perform the listed bindary operation on the first two elements on
00284   // the stack.
00285 
00286   TAO_Literal_Constraint result =
00287     (operation <= TAO_NE)
00288     ?
00289     TAO_Literal_Constraint
00290     ((CORBA::Boolean)
00291      ((operation == TAO_GT) ? l_op > r_op :
00292       (operation == TAO_GE) ? l_op >= r_op :
00293       (operation == TAO_LT) ? l_op < r_op :
00294       (operation == TAO_LE) ? l_op <= r_op :
00295       (operation == TAO_NE) ? l_op != r_op :
00296       (operation == TAO_EQ) ? l_op == r_op : 0))
00297     :
00298     ((operation == TAO_PLUS) ? l_op + r_op :
00299      (operation == TAO_MINUS) ? l_op - r_op :
00300      (operation == TAO_MULT) ? l_op * r_op :
00301      (operation == TAO_DIV) ? l_op / r_op :
00302      TAO_Literal_Constraint ());
00303 
00304   this->queue_.dequeue_operand ();
00305   this->queue_.dequeue_operand ();
00306   this->queue_.enqueue_head (result);
00307 }
00308 
00309 int
00310 TAO_Constraint_Evaluator::visit_bin_op (TAO_Binary_Constraint* op,
00311                                         int operation)
00312 {
00313   int return_value = -1;
00314   TAO_Constraint* left = op->left_operand ();
00315   TAO_Constraint* right = op->right_operand ();
00316 
00317   // Perform an operation on the results of evaluating the left and
00318   // right branches of this subtree.
00319   if (left->accept (this) == 0)
00320     {
00321       if (right->accept (this) == 0)
00322         {
00323           this->do_the_op (operation);
00324           return_value = 0;
00325         }
00326       else
00327         this->queue_.dequeue_operand ();
00328     }
00329 
00330   return return_value;
00331 }
00332 
00333 int
00334 TAO_Constraint_Evaluator::
00335 visit_add(TAO_Binary_Constraint* boolean_add)
00336 {
00337   return this->visit_bin_op (boolean_add, TAO_PLUS);
00338 }
00339 
00340 int
00341 TAO_Constraint_Evaluator::
00342 visit_sub (TAO_Binary_Constraint* boolean_sub)
00343 {
00344   return this->visit_bin_op (boolean_sub, TAO_MINUS);
00345 }
00346 
00347 int
00348 TAO_Constraint_Evaluator::
00349 visit_mult (TAO_Binary_Constraint* boolean_mult)
00350 {
00351   return this->visit_bin_op (boolean_mult, TAO_MULT);
00352 }
00353 
00354 int
00355 TAO_Constraint_Evaluator::
00356 visit_div (TAO_Binary_Constraint* boolean_div)
00357 {
00358   return this->visit_bin_op (boolean_div, TAO_DIV);
00359 }
00360 
00361 int
00362 TAO_Constraint_Evaluator::
00363 visit_twiddle (TAO_Binary_Constraint* binary_twiddle)
00364 {
00365   int return_value = -1;
00366   TAO_Constraint* left = binary_twiddle->left_operand (),
00367     *right = binary_twiddle->right_operand ();
00368 
00369   // Determine if the left operand is a substring of the right.
00370 
00371   if (left->accept (this) == 0)
00372     {
00373       if (right->accept (this) == 0)
00374         {
00375           TAO_Literal_Constraint& left_operand = this->queue_.get_left_operand ();
00376           TAO_Literal_Constraint& right_operand = this->queue_.get_right_operand ();
00377 
00378           CORBA::Boolean result = (CORBA::Boolean)
00379             (ACE_OS::strstr ((const char*)right_operand,
00380                              (const char*)left_operand) != 0);
00381 
00382           this->queue_.dequeue_operand ();
00383           this->queue_.dequeue_operand ();
00384           this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00385           return_value = 0;
00386         }
00387       else
00388         this->queue_.dequeue_operand ();
00389     }
00390 
00391   return return_value;
00392 }
00393 
00394 int
00395 TAO_Constraint_Evaluator::
00396 visit_in(TAO_Binary_Constraint* binary_in)
00397 {
00398   int return_value = -1;
00399   TAO_Constraint* left = binary_in->left_operand (),
00400     *right = binary_in->right_operand ();
00401 
00402   // Determine if the left operand is contained in the right.
00403 
00404   if (left->accept (this) == 0)
00405     {
00406       if (this->visit_property ((TAO_Property_Constraint*) right) == 0)
00407         {
00408           TAO_Literal_Constraint& left_value = this->queue_.get_left_operand();
00409           const CORBA::Any* any = (const CORBA::Any*) this->queue_.get_right_operand();
00410 
00411           if (any != 0)
00412             {
00413               CORBA::Boolean result =
00414                 this->sequence_does_contain ((CORBA::Any*) any, left_value);
00415 
00416               this->queue_.dequeue_operand ();
00417               this->queue_.dequeue_operand ();
00418               this->queue_.enqueue_head (TAO_Literal_Constraint (result));
00419               return_value = 0;
00420             }
00421           else
00422             this->queue_.dequeue_operand ();
00423         }
00424     }
00425 
00426   return return_value;
00427 }
00428 
00429 int
00430 TAO_Constraint_Evaluator::
00431 visit_less_than (TAO_Binary_Constraint* boolean_lt)
00432 {
00433   return this->visit_bin_op (boolean_lt, TAO_LT);
00434 }
00435 
00436 int
00437 TAO_Constraint_Evaluator::
00438 visit_less_than_equal (TAO_Binary_Constraint* boolean_lte)
00439 {
00440   return this->visit_bin_op (boolean_lte, TAO_LE);
00441 }
00442 
00443 int
00444 TAO_Constraint_Evaluator::
00445 visit_greater_than (TAO_Binary_Constraint* boolean_gt)
00446 {
00447   return this->visit_bin_op (boolean_gt, TAO_GT);
00448 }
00449 
00450 int
00451 TAO_Constraint_Evaluator::
00452 visit_greater_than_equal (TAO_Binary_Constraint* boolean_gte)
00453 {
00454   return this->visit_bin_op (boolean_gte, TAO_GE);
00455 }
00456 
00457 int
00458 TAO_Constraint_Evaluator::
00459 visit_equal (TAO_Binary_Constraint* boolean_eq)
00460 {
00461   return this->visit_bin_op (boolean_eq, TAO_EQ);
00462 }
00463 
00464 int
00465 TAO_Constraint_Evaluator::
00466 visit_not_equal (TAO_Binary_Constraint* boolean_neq)
00467 {
00468   return this->visit_bin_op (boolean_neq, TAO_NE);
00469 }
00470 
00471 int
00472 TAO_Constraint_Evaluator::
00473 visit_literal (TAO_Literal_Constraint* literal)
00474 {
00475   this->queue_.enqueue_head (*literal);
00476   return 0;
00477 }
00478 
00479 int
00480 TAO_Constraint_Evaluator::
00481 visit_property (TAO_Property_Constraint* literal)
00482 {
00483   ACE_UNUSED_ARG (literal);
00484   return -1;
00485   // A derived class decides how to do this.
00486 }
00487 
00488 /*@@ pradeep: where is this used?
00489 
00490 CORBA::Boolean
00491 TAO_find_string (CosTradingSequences::StringSeq& sequence,
00492                  const char* element)
00493 {
00494  int length = sequence.length (),
00495     return_value = 0;
00496 
00497   for (int i = 0; i < length; i++)
00498     {
00499       if (ACE_OS::strcmp (sequence[i], element) == 0)
00500         {
00501           return_value = 1;
00502           break;
00503         }
00504     }
00505 
00506   return (CORBA::Boolean) return_value;
00507 }
00508 */
00509 
00510 CORBA::Boolean
00511 TAO_Constraint_Evaluator::
00512 sequence_does_contain (CORBA::Any* sequence,
00513                       TAO_Literal_Constraint& element)
00514 {
00515   // Helper method to cast the void* value returned from the sequence
00516   // any into a sequence type locally compiled from idl. The sequence
00517   // wrapper uses the [] operator to locate the target element in the
00518   // sequence.
00519 
00520   CORBA::Boolean return_value = 0;
00521   CORBA::TypeCode_var type = sequence->type ();
00522   CORBA::TCKind sequence_type = CORBA::tk_void;
00523   try
00524     {
00525       sequence_type =
00526         TAO_Sequence_Extracter_Base::sequence_type (type.in ());
00527     }
00528   catch (const CORBA::Exception&)
00529     {
00530       return return_value;
00531     }
00532 
00533   if (sequence_type == CORBA::tk_void)
00534     return return_value;
00535 
00536   switch (sequence_type)
00537     {
00538     case CORBA::tk_short:
00539       {
00540         CORBA::LongLong value = element;
00541         return_value = ::TAO_find (*sequence, static_cast<CORBA::Short> (value));
00542       }
00543     break;
00544     case CORBA::tk_ushort:
00545       {
00546         CORBA::ULongLong value = element;
00547         return_value = ::TAO_find (*sequence, static_cast<CORBA::UShort> (value));
00548       }
00549       break;
00550     case CORBA::tk_long:
00551       {
00552         CORBA::LongLong value = element;
00553         return_value = ::TAO_find (*sequence, static_cast<CORBA::Long> (value));
00554       }
00555       break;
00556     case CORBA::tk_ulong:
00557       {
00558         CORBA::ULongLong value = element;
00559         return_value = ::TAO_find (*sequence, static_cast<CORBA::ULong> (value));
00560       }
00561       break;
00562     case CORBA::tk_longlong:
00563       {
00564         CORBA::LongLong value = element;
00565         return_value = ::TAO_find (*sequence, value);
00566       }
00567       break;
00568     case CORBA::tk_ulonglong:
00569       {
00570         CORBA::ULongLong value = element;
00571         return_value = ::TAO_find (*sequence, value);
00572       }
00573       break;
00574     case CORBA::tk_float:
00575       {
00576         CORBA::Double value = element;
00577         return_value = ::TAO_find (*sequence, static_cast<CORBA::Float> (value));
00578       }
00579       break;
00580     case CORBA::tk_double:
00581       {
00582         CORBA::Double value = element;
00583         return_value = ::TAO_find (*sequence, value);
00584       }
00585       break;
00586     case CORBA::tk_boolean:
00587       {
00588         CORBA::Boolean value = element;
00589         return_value = ::TAO_find (*sequence, value);
00590       }
00591       break;
00592     case CORBA::tk_string:
00593       {
00594         const char* value = element;
00595         return_value = ::TAO_find (*sequence, value);
00596       }
00597       break;
00598     default:
00599       break;
00600     }
00601 
00602   return return_value;
00603 }
00604 
00605 // Explicit template specializations
00606 
00607 int
00608 TAO_Element_Equal<CORBA::Short>::
00609 operator () (TAO_DynSequence_i& dyn_any,
00610              CORBA::Short element) const
00611 {
00612   int return_value = 0;
00613   try
00614     {
00615       CORBA::Short value = dyn_any.get_short ();
00616       return_value = (value == element);
00617     }
00618   catch (const CORBA::Exception&)
00619     {
00620     }
00621   return return_value;
00622 }
00623 
00624 int
00625 TAO_Element_Equal<CORBA::UShort>::
00626 operator () (TAO_DynSequence_i& dyn_any,
00627              CORBA::UShort element) const
00628 {
00629   int return_value = 0;
00630   try
00631     {
00632       CORBA::UShort value = dyn_any.get_ushort ();
00633       return_value = (value == element);
00634     }
00635   catch (const CORBA::Exception&)
00636     {
00637     }
00638   return return_value;
00639 }
00640 
00641 int
00642 TAO_Element_Equal<CORBA::Long>::
00643 operator () (TAO_DynSequence_i& dyn_any,
00644              CORBA::Long element) const
00645 {
00646   int return_value = 0;
00647   try
00648     {
00649       CORBA::Long value = dyn_any.get_long ();
00650       return_value = (value == element);
00651     }
00652   catch (const CORBA::Exception&)
00653     {
00654     }
00655   return return_value;
00656 }
00657 
00658 int
00659 TAO_Element_Equal<CORBA::ULong>::
00660 operator () (TAO_DynSequence_i& dyn_any,
00661              CORBA::ULong element) const
00662 {
00663   int return_value = 0;
00664   try
00665     {
00666       CORBA::ULong value = dyn_any.get_ulong ();
00667       return_value = (value == element);
00668     }
00669   catch (const CORBA::Exception&)
00670     {
00671     }
00672   return return_value;
00673 }
00674 
00675 int
00676 TAO_Element_Equal<CORBA::LongLong>::
00677 operator () (TAO_DynSequence_i& dyn_any,
00678              CORBA::LongLong element) const
00679 {
00680   int return_value = 0;
00681   try
00682     {
00683       CORBA::LongLong value = dyn_any.get_longlong ();
00684       return_value = (value == element);
00685     }
00686   catch (const CORBA::Exception&)
00687     {
00688     }
00689   return return_value;
00690 }
00691 
00692 int
00693 TAO_Element_Equal<CORBA::ULongLong>::
00694 operator () (TAO_DynSequence_i& dyn_any,
00695              CORBA::ULongLong element) const
00696 {
00697   int return_value = 0;
00698   try
00699     {
00700       CORBA::ULongLong value = dyn_any.get_ulonglong ();
00701       return_value = (value == element);
00702     }
00703   catch (const CORBA::Exception&)
00704     {
00705     }
00706   return return_value;
00707 }
00708 
00709 int
00710 TAO_Element_Equal<CORBA::Float>::
00711 operator () (TAO_DynSequence_i& dyn_any,
00712              CORBA::Float element) const
00713 {
00714   int return_value = 0;
00715   try
00716     {
00717       CORBA::Float value = dyn_any.get_float ();
00718       return_value = (value == element);
00719     }
00720   catch (const CORBA::Exception&){}
00721   return return_value;
00722 }
00723 
00724 int
00725 TAO_Element_Equal<CORBA::Double>::
00726 operator () (TAO_DynSequence_i& dyn_any,
00727              CORBA::Double element) const
00728 {
00729   int return_value = 0;
00730   try
00731     {
00732       CORBA::Double value = dyn_any.get_double ();
00733       return_value = (value == element);
00734     }
00735   catch (const CORBA::Exception&){}
00736   return return_value;
00737 }
00738 
00739 int
00740 TAO_Element_Equal<CORBA::Boolean>::
00741 operator () (TAO_DynSequence_i& dyn_any,
00742              CORBA::Boolean element) const
00743 {
00744   int return_value = 0;
00745   try
00746     {
00747     CORBA::Boolean value = (CORBA::Boolean) dyn_any.get_short ();
00748       return_value = (value == element);
00749     }
00750   catch (const CORBA::Exception&){}
00751   return return_value;
00752 }
00753 
00754 int
00755 TAO_Element_Equal<const char*>::
00756 operator () (TAO_DynSequence_i& dyn_any,
00757              const char* element) const
00758 {
00759   int return_value = 0;
00760   try
00761     {
00762       const char* value = dyn_any.get_string ();
00763       return_value = (ACE_OS::strcmp (value, element) == 0);
00764     }
00765   catch (const CORBA::Exception&){}
00766   return return_value;
00767 }
00768 
00769 TAO_Constraint_Validator::
00770 TAO_Constraint_Validator (void)
00771 {
00772   // No-Op.
00773 }
00774 
00775 TAO_Constraint_Validator::~TAO_Constraint_Validator (void)
00776 {
00777   for (TAO_Typecode_Table::iterator type_iter (this->type_map_);
00778        ! type_iter.done ();
00779        type_iter++)
00780     {
00781       CORBA::TypeCode_ptr corba_type = (*type_iter).int_id_;
00782       CORBA::release (corba_type);
00783     }
00784 }
00785 
00786 int
00787 TAO_Constraint_Validator::validate (TAO_Constraint* root)
00788 {
00789   return root->accept(this);
00790 }
00791 
00792 int
00793 TAO_Constraint_Validator::visit_constraint (TAO_Unary_Constraint* constraint)
00794 {
00795   int return_value = -1;
00796   TAO_Expression_Type type;
00797   TAO_Constraint* operand = constraint->operand ();
00798   this->extract_type (operand, type);
00799 
00800   if (this->expr_returns_boolean (type))
00801     return_value =  operand->accept (this);
00802 
00803   return return_value;
00804 }
00805 
00806 int
00807 TAO_Constraint_Validator::visit_first (TAO_Noop_Constraint *)
00808 {
00809   return 0;
00810 }
00811 
00812 int
00813 TAO_Constraint_Validator::visit_random (TAO_Noop_Constraint *)
00814 {
00815   return 0;
00816 }
00817 
00818 int
00819 TAO_Constraint_Validator::visit_with (TAO_Unary_Constraint* unary_with)
00820 {
00821   return this->visit_constraint (unary_with);
00822 }
00823 
00824 int
00825 TAO_Constraint_Validator::visit_min (TAO_Unary_Constraint* unary_min)
00826 {
00827   return this->visit_unary_minus (unary_min);
00828 }
00829 
00830 int
00831 TAO_Constraint_Validator::visit_max (TAO_Unary_Constraint* unary_max)
00832 {
00833   return this->visit_unary_minus (unary_max);
00834 }
00835 
00836 int
00837 TAO_Constraint_Validator::
00838 visit_and (TAO_Binary_Constraint* boolean_and)
00839 {
00840   int return_value = -1;
00841   TAO_Constraint* left = boolean_and->left_operand (),
00842     *right = boolean_and->right_operand ();
00843   TAO_Expression_Type left_type, right_type;
00844   this->extract_type (left, left_type);
00845   this->extract_type (right, right_type);
00846 
00847   // Can only "and" expressions that return a boolean value
00848   if (this->expr_returns_boolean (left_type) &&
00849       this->expr_returns_boolean (right_type))
00850     {
00851       if (left->accept (this) == 0 &&
00852           right->accept (this) == 0)
00853         return_value = 0;
00854     }
00855 
00856   return return_value;
00857 }
00858 
00859 int
00860 TAO_Constraint_Validator::
00861 visit_or(TAO_Binary_Constraint* boolean_or)
00862 {
00863   // The types for or are the same as those for and.
00864   return this->visit_and (boolean_or);
00865 }
00866 
00867 int
00868 TAO_Constraint_Validator::
00869 visit_not (TAO_Unary_Constraint* unary_not)
00870 {
00871   int return_value = -1;
00872   // Not can only negate an expression that returns a boolean.
00873   TAO_Expression_Type type;
00874   TAO_Constraint* operand = unary_not->operand ();
00875   this->extract_type (operand, type);
00876 
00877   if (this->expr_returns_boolean (type))
00878     return_value = operand->accept (this);
00879 
00880   return return_value;
00881 }
00882 
00883 int
00884 TAO_Constraint_Validator::
00885 visit_exist (TAO_Unary_Constraint* unary_exist)
00886 {
00887   // Exist simply requires that its operand be a property name
00888   // included in the service type.
00889   int return_value = -1;
00890   TAO_Constraint* operand = unary_exist->operand ();
00891   TAO_Expression_Type type = operand->expr_type ();
00892 
00893   if (type == TAO_IDENT)
00894     return_value = operand->accept (this);
00895 
00896   return return_value;
00897 }
00898 
00899 int
00900 TAO_Constraint_Validator::
00901 visit_unary_minus (TAO_Unary_Constraint* unary_minus)
00902 {
00903   // Unary minus can only negate a numeric operand.
00904   int return_value = -1;
00905   TAO_Expression_Type type;
00906   TAO_Constraint* operand = unary_minus->operand ();
00907   this->extract_type (operand, type);
00908 
00909   if (this->expr_returns_number (type))
00910     return_value = operand->accept (this);
00911 
00912   return return_value;
00913 }
00914 
00915 int
00916 TAO_Constraint_Validator::
00917 visit_add (TAO_Binary_Constraint* boolean_add)
00918 {
00919   // All the mathematical operators require numeric operands.
00920   int return_value = -1;
00921   TAO_Constraint* left = boolean_add->left_operand (),
00922     *right = boolean_add->right_operand ();
00923   TAO_Expression_Type left_type, right_type;
00924   this->extract_type (left, left_type);
00925   this->extract_type (right, right_type);
00926 
00927   if (this->expr_returns_number (left_type) &&
00928       this->expr_returns_number (right_type))
00929     {
00930       if (left->accept (this) == 0 &&
00931           right->accept (this) == 0)
00932         return_value = 0;
00933     }
00934 
00935   return return_value;
00936 }
00937 
00938 int
00939 TAO_Constraint_Validator::
00940 visit_sub (TAO_Binary_Constraint* boolean_sub)
00941 {
00942   return this->visit_add (boolean_sub);
00943 }
00944 
00945 int
00946 TAO_Constraint_Validator::
00947 visit_mult (TAO_Binary_Constraint* boolean_mult)
00948 {
00949   return this->visit_add (boolean_mult);
00950 }
00951 
00952 int
00953 TAO_Constraint_Validator::
00954 visit_div (TAO_Binary_Constraint* boolean_div)
00955 {
00956   // Div not only requires that both of its operands be numeric, but
00957   // also the the demoninator not be zero. However, since the
00958   // denominator can be an expression who's value can only be
00959   // determined while evaulating the constraint expression, this
00960   // method detects only when the demoniator is a literal whose value
00961   // is zero.
00962   int return_value = -1;
00963   TAO_Constraint* left = boolean_div->left_operand (),
00964     *right = boolean_div->right_operand ();
00965   TAO_Expression_Type left_type, right_type;
00966   this->extract_type (left, left_type);
00967   this->extract_type (right, right_type);
00968 
00969   if (this->expr_returns_number (left_type) &&
00970       this->expr_returns_number (right_type))
00971     {
00972       // Prevent division by zero, a no no.
00973       int right_isnt_zero = 1;
00974       switch(right->expr_type ())
00975         {
00976         case TAO_UNSIGNED:
00977           right_isnt_zero =
00978             (static_cast<CORBA::ULongLong>
00979                (*dynamic_cast<TAO_Literal_Constraint*> (right)) != 0);
00980           break;
00981         case TAO_SIGNED:
00982           right_isnt_zero =
00983             (static_cast<CORBA::LongLong>
00984                (*dynamic_cast<TAO_Literal_Constraint*> (right)) != 0);
00985           break;
00986         case TAO_DOUBLE:
00987           right_isnt_zero =
00988             (static_cast<CORBA::Double>
00989                (*dynamic_cast<TAO_Literal_Constraint*> (right)) != 0.0);
00990           break;
00991         }
00992 
00993       if (right_isnt_zero)
00994         {
00995           if (left->accept (this) == 0 &&
00996               right->accept (this) == 0)
00997             return_value = 0;
00998         }
00999     }
01000 
01001   return return_value;
01002 }
01003 
01004 int
01005 TAO_Constraint_Validator::
01006 visit_twiddle (TAO_Binary_Constraint* binary_twiddle)
01007 {
01008   // Twiddle requires that both of its operand be strings.
01009   int return_value = -1;
01010   TAO_Constraint* left = binary_twiddle->left_operand (),
01011     *right = binary_twiddle->right_operand ();
01012   TAO_Expression_Type left_type, right_type;
01013   this->extract_type (left, left_type);
01014   this->extract_type (right, right_type);
01015 
01016   if  (this->expr_returns_string (left_type) &&
01017       this->expr_returns_string (right_type))
01018     {
01019       if (left->accept (this) == 0 &&
01020           right->accept (this) == 0)
01021         return_value = 0;
01022     }
01023 
01024   return return_value;
01025 }
01026 
01027 int
01028 TAO_Constraint_Validator::
01029 visit_in (TAO_Binary_Constraint* binary_in)
01030 {
01031   // In requires that the right operand be a sequence of a simple type
01032   // and that its left operand be an expression that evaluates to a
01033   // value of the same simple type.
01034   int return_value = -1;
01035   TAO_Expression_Type left_type, right_type;
01036   TAO_Constraint
01037     *left = binary_in->left_operand (),
01038     *right = binary_in->right_operand ();
01039 
01040   CORBA::TypeCode* prop_type = this->extract_type (right, right_type);
01041   this->extract_type (left, left_type);
01042 
01043   if (right_type == TAO_SEQUENCE)
01044     {
01045       CORBA::Boolean types_match = 0;
01046       CORBA::TCKind seq_type = CORBA::tk_void;
01047       try
01048         {
01049           seq_type =
01050             TAO_Sequence_Extracter_Base::sequence_type (prop_type);
01051         }
01052       catch (const CORBA::Exception&)
01053         {
01054           return return_value;
01055         }
01056 
01057       if (seq_type != CORBA::tk_void)
01058         {
01059           if (this->expr_returns_number (left_type))
01060             {
01061               types_match = (seq_type == CORBA::tk_short ||
01062                              seq_type == CORBA::tk_ushort ||
01063                              seq_type == CORBA::tk_long ||
01064                              seq_type == CORBA::tk_ulong ||
01065                              seq_type == CORBA::tk_longlong ||
01066                              seq_type == CORBA::tk_ulonglong ||
01067                              seq_type == CORBA::tk_float ||
01068                              seq_type == CORBA::tk_double);
01069             }
01070           else if (this->expr_returns_boolean (left_type))
01071             types_match = (seq_type == CORBA::tk_boolean);
01072           else if (this->expr_returns_string (left_type))
01073             types_match = (seq_type == CORBA::tk_string);
01074 
01075           if (types_match)
01076             return_value = left->accept (this);
01077         }
01078     }
01079 
01080   return return_value;
01081 }
01082 
01083 int
01084 TAO_Constraint_Validator::
01085 visit_less_than(TAO_Binary_Constraint* boolean_lt)
01086 {
01087   // Comparison operations require that both operands be of the same
01088   // simple type.
01089   int return_value = -1;
01090   TAO_Constraint* left = boolean_lt->left_operand (),
01091     *right = boolean_lt->right_operand ();
01092   TAO_Expression_Type left_type, right_type;
01093   this->extract_type (left, left_type);
01094   this->extract_type (right, right_type);
01095 
01096   if ((this->expr_returns_number (left_type) &&
01097        this->expr_returns_number (right_type)) ||
01098       (this->expr_returns_string (left_type) &&
01099        this->expr_returns_string (right_type)))
01100     {
01101       if (left->accept (this) == 0 &&
01102           right->accept (this) == 0)
01103         return_value = 0;
01104     }
01105 
01106   return return_value;
01107 }
01108 
01109 int
01110 TAO_Constraint_Validator::
01111 visit_less_than_equal (TAO_Binary_Constraint* boolean_lte)
01112 {
01113   return this->visit_less_than (boolean_lte);
01114 }
01115 
01116 int
01117 TAO_Constraint_Validator::
01118 visit_greater_than (TAO_Binary_Constraint* boolean_gt)
01119 {
01120   return this->visit_less_than (boolean_gt);
01121 }
01122 
01123 int
01124 TAO_Constraint_Validator::
01125 visit_greater_than_equal (TAO_Binary_Constraint* boolean_gte)
01126 {
01127   return this->visit_less_than(boolean_gte);
01128 }
01129 
01130 int
01131 TAO_Constraint_Validator::
01132 visit_equal (TAO_Binary_Constraint* boolean_eq)
01133 {
01134   int return_value = -1;
01135   TAO_Constraint* left = boolean_eq->left_operand (),
01136     *right = boolean_eq->right_operand ();
01137   TAO_Expression_Type left_type, right_type;
01138   this->extract_type (left, left_type);
01139   this->extract_type (right, right_type);
01140 
01141   if ((this->expr_returns_number (left_type) &&
01142        this->expr_returns_number (right_type)) ||
01143       (this->expr_returns_string (left_type) &&
01144        this->expr_returns_string (right_type)) ||
01145       (this->expr_returns_boolean (left_type) &&
01146        this->expr_returns_boolean (right_type)))
01147     {
01148       if (left->accept (this) == 0 &&
01149           right->accept (this) == 0)
01150         return_value = 0;
01151     }
01152 
01153   return return_value;
01154 }
01155 
01156 int
01157 TAO_Constraint_Validator::
01158 visit_not_equal (TAO_Binary_Constraint* boolean_neq)
01159 {
01160   return this->visit_equal (boolean_neq);
01161 }
01162 
01163 int
01164 TAO_Constraint_Validator::
01165 visit_literal (TAO_Literal_Constraint *)
01166 {
01167   return 0;
01168 }
01169 
01170 int
01171 TAO_Constraint_Validator::
01172 visit_property (TAO_Property_Constraint *)
01173 {
01174   return 0;
01175 }
01176 
01177 CORBA::TypeCode*
01178 TAO_Constraint_Validator::extract_type (TAO_Constraint* expr,
01179                                         TAO_Expression_Type& type)
01180 {
01181   CORBA::TypeCode* return_value = 0;
01182 
01183   type = expr->expr_type ();
01184   if (type == TAO_IDENT)
01185     {
01186       TAO_Property_Constraint* prop = (TAO_Property_Constraint*) expr;
01187       CORBA::String_var prop_name (prop->name ());
01188 
01189       if (this->type_map_.find (prop_name, return_value) == 0)
01190         type = TAO_Literal_Constraint::comparable_type (return_value);
01191     }
01192 
01193   return return_value;
01194 }
01195 
01196 int
01197 TAO_Constraint_Validator::expr_returns_boolean (TAO_Expression_Type expr_type)
01198 {
01199   // If the expression is a boolean operations, a boolean literal, or
01200   // a boolean property, return 1.
01201   int return_value = 0;
01202 
01203   if (expr_type <= TAO_BOOLEAN)
01204     return_value = 1;
01205 
01206   return return_value;
01207 }
01208 
01209 
01210 int
01211 TAO_Constraint_Validator::expr_returns_number (TAO_Expression_Type expr_type)
01212 {
01213   // If the expression is a number operation, a numeric literal, or a
01214   // numeric property, return 1.
01215   int return_value = 0;
01216 
01217   if ((expr_type >= TAO_PLUS && expr_type <= TAO_NUMBER) ||
01218       (expr_type >= TAO_SIGNED && expr_type <= TAO_DOUBLE))
01219     return_value = 1;
01220 
01221   return return_value;
01222 }
01223 
01224 int
01225 TAO_Constraint_Validator::expr_returns_string (TAO_Expression_Type expr_type)
01226 {
01227   // If the expression is an operation with a string return value, a
01228   // string literal, or a property whose type is string, return 1.
01229   int return_value = 0;
01230 
01231   if (expr_type == TAO_STRING)
01232     return_value = 1;
01233 
01234   return return_value;
01235 }
01236 
01237 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:49:26 2010 for TAO_CosTrader by  doxygen 1.4.7