Constraint_Visitors.cpp

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

Generated on Thu Nov 9 13:59:57 2006 for TAO_CosTrader by doxygen 1.3.6