Constraint_Visitors.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 //=============================================================================
00004 /**
00005  *  @file Constraint_Visitors.h
00006  *
00007  *  Constraint_Visitors.h,v 1.27 2005/11/24 11:05:44 ossama Exp
00008  *
00009  *  @author Seth Widoff <sbw1@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 
00014 #ifndef TAO_CONSTRAINT_VISITOR_H
00015 #define TAO_CONSTRAINT_VISITOR_H
00016 #include /**/ "ace/pre.h"
00017 
00018 #include "orbsvcs/Trader/Interpreter_Utils.h"
00019 #include "orbsvcs/Trader/trading_serv_export.h"
00020 #include "ace/Containers.h"
00021 
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 class TAO_DynSequence_i;
00025 
00026 class TAO_Constraint;
00027 class TAO_Unary_Constraint;
00028 class TAO_Binary_Constraint;
00029 class TAO_Literal_Constraint;
00030 class TAO_Property_Constraint;
00031 class TAO_Noop_Constraint;
00032 
00033 /**
00034  * @class TAO_Constraint_Visitor
00035  *
00036  * @brief This is the base class for all visitors who wish to preform
00037  * some operation from the state of the expression tree. Using
00038  * double dispatching, subclasses of Constraint expression call
00039  * back to the InterpreterVisitor subclass from the accept
00040  * method.
00041  *
00042  * Traversal of the expression tree uses the "Visitor"
00043  * pattern. To "visit" a node, a client invokes the "accept"
00044  * method on a subclass of ConstraintExpression, which, in turn,
00045  * invokes the appropriate method on the visitor passed to it,
00046  * based on its own type. So, the Constraint_Visitor has a
00047  * method to deal with each possible type of node in an
00048  * expression tree; one for each operator in the grammar.
00049  */
00050 class TAO_Trading_Serv_Export TAO_Constraint_Visitor
00051 {
00052 public:
00053 
00054   virtual ~TAO_Constraint_Visitor (void) {}
00055 
00056   virtual int visit_constraint (TAO_Unary_Constraint* constraint) = 0;
00057 
00058   virtual int visit_with (TAO_Unary_Constraint* unary_with) = 0;
00059   virtual int visit_min (TAO_Unary_Constraint* unary_min) = 0;
00060   virtual int visit_max (TAO_Unary_Constraint* unary_max) = 0;
00061   virtual int visit_first (TAO_Noop_Constraint* noop_first) = 0;
00062   virtual int visit_random (TAO_Noop_Constraint* noop_random) = 0;
00063 
00064   virtual int visit_and (TAO_Binary_Constraint* boolean_and) = 0;
00065   virtual int visit_or (TAO_Binary_Constraint* boolean_or) = 0;
00066   virtual int visit_not (TAO_Unary_Constraint* unary_not) = 0;
00067 
00068   virtual int visit_exist (TAO_Unary_Constraint* unary_exist) = 0;
00069   virtual int visit_unary_minus (TAO_Unary_Constraint* unary_minus) = 0;
00070 
00071   virtual int visit_add (TAO_Binary_Constraint* boolean_add) = 0;
00072   virtual int visit_sub (TAO_Binary_Constraint* boolean_sub) = 0;
00073   virtual int visit_mult (TAO_Binary_Constraint* boolean_mult) = 0;
00074   virtual int visit_div (TAO_Binary_Constraint* boolean_div) = 0;
00075 
00076   virtual int visit_twiddle (TAO_Binary_Constraint* binary_twiddle) = 0;
00077   virtual int visit_in (TAO_Binary_Constraint* binary_in) = 0;
00078 
00079   virtual int visit_less_than (TAO_Binary_Constraint* boolean_lt) = 0;
00080   virtual int visit_less_than_equal (TAO_Binary_Constraint* boolean_lte) = 0;
00081   virtual int visit_greater_than (TAO_Binary_Constraint* boolean_gt) = 0;
00082   virtual int visit_greater_than_equal (TAO_Binary_Constraint* boolean_gte) = 0;
00083   virtual int visit_equal (TAO_Binary_Constraint* boolean_eq) = 0;
00084   virtual int visit_not_equal (TAO_Binary_Constraint* boolean_neq) = 0;
00085 
00086   virtual int visit_literal (TAO_Literal_Constraint* literal) = 0;
00087   virtual int visit_property (TAO_Property_Constraint* literal) = 0;
00088 };
00089 
00090 TAO_END_VERSIONED_NAMESPACE_DECL
00091 
00092 #include "orbsvcs/Trader/Constraint_Nodes.h"
00093 
00094 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00095 
00096 /**
00097  * @class TAO_Constraint_Validator
00098  *
00099  * @brief TAO_Constraint_Validator ensures that in an expression tree
00100  * passed to it, the operands of each operation match the
00101  * correct types.
00102  *
00103  * TAO_Constraint_Validator uses the visitor pattern to
00104  * traverse all the nodes in an expression tree, checking that
00105  * for each operator node the operands are of the proper data
00106  * type it they're literals, or that they exist in the service
00107  * type definition _and_ have the proper type, if they're
00108  * property names. The algorithm for type
00109  * checking is as follows: ensure that operand expression(s)
00110  * return the correct types using expr_returns* methods. If they
00111  * (or it) return the correct types, call accept
00112  * on each operand until all return true or one returns false,
00113  * at which point we can back out of the traversal and indicate
00114  * failure.
00115  */
00116 class TAO_Trading_Serv_Export TAO_Constraint_Validator : public TAO_Constraint_Visitor
00117 {
00118 public:
00119   /// Constructor.
00120   TAO_Constraint_Validator (void);
00121 
00122   /// Destructor.
00123   virtual ~TAO_Constraint_Validator (void);
00124 
00125   /**
00126    * Validate returns 1 if the expression tree whose root is <root>
00127    * makes semantic sense, in that the operands for each operation
00128    * comply with each other and the types accepted by the operator.
00129    */
00130   int validate (TAO_Constraint* root);
00131 
00132   // = Visitor Methods
00133 
00134   virtual int visit_constraint (TAO_Unary_Constraint* constraint);
00135 
00136   virtual int visit_with (TAO_Unary_Constraint* unary_with);
00137   virtual int visit_min (TAO_Unary_Constraint* unary_min);
00138   virtual int visit_max (TAO_Unary_Constraint* unary_max);
00139   virtual int visit_first (TAO_Noop_Constraint* noop_first);
00140   virtual int visit_random (TAO_Noop_Constraint* noop_random);
00141 
00142   /// The two operands must return a boolean value.
00143   virtual int visit_and (TAO_Binary_Constraint* boolean_and);
00144   virtual int visit_or (TAO_Binary_Constraint* boolean_or);
00145 
00146   /// The operand must return a boolean value.
00147   virtual int visit_not (TAO_Unary_Constraint* unary_not);
00148 
00149   /// The operand must return a valid  (i.e., present in the service
00150   /// type description) property name.
00151   virtual int visit_exist (TAO_Unary_Constraint* unary_exist);
00152 
00153   /// The operand must return a number to be negated.
00154   virtual int visit_unary_minus (TAO_Unary_Constraint* unary_minus);
00155 
00156   /// Both operands must return numeric results.
00157   virtual int visit_add (TAO_Binary_Constraint* boolean_add);
00158   virtual int visit_sub (TAO_Binary_Constraint* boolean_sub);
00159   virtual int visit_mult (TAO_Binary_Constraint* boolean_mult);
00160   virtual int visit_div (TAO_Binary_Constraint* boolean_div);
00161 
00162   /// Both operands must return strings.
00163   virtual int visit_twiddle (TAO_Binary_Constraint* binary_twiddle);
00164 
00165   /// The right operand must be a sequence of the same simple type as
00166   /// the left operand.
00167   virtual int visit_in (TAO_Binary_Constraint* binary_in);
00168 
00169   /// The left and right operands must both be of the same simple type.
00170   virtual int visit_less_than (TAO_Binary_Constraint* boolean_lt);
00171   virtual int visit_less_than_equal (TAO_Binary_Constraint* boolean_lte);
00172   virtual int visit_greater_than (TAO_Binary_Constraint* boolean_gt);
00173   virtual int visit_greater_than_equal (TAO_Binary_Constraint* boolean_gte);
00174   virtual int visit_equal (TAO_Binary_Constraint* boolean_eq);
00175   virtual int visit_not_equal (TAO_Binary_Constraint* boolean_neq);
00176 
00177   /// The property must be defined in the service type description.
00178   virtual int visit_literal (TAO_Literal_Constraint* literal);
00179   virtual int visit_property (TAO_Property_Constraint* literal);
00180 
00181 protected:
00182 
00183   /// A map gleaned from the ServiceTypeStruct, which correlates
00184   /// property names with their types.
00185   TAO_Typecode_Table type_map_;
00186 
00187 private:
00188 
00189   CORBA::TypeCode* extract_type (TAO_Constraint* expr_type,
00190                                  TAO_Expression_Type& type);
00191 
00192   /// expr_returns_boolean returns 1 if <expr_type>, when evaluated, will
00193   /// return a boolean.
00194   int expr_returns_boolean (TAO_Expression_Type expr_type);
00195 
00196   /// expr_returns_boolean returns 1 if <expr_type>, when evaluated, will
00197   /// return a number.
00198   int expr_returns_number (TAO_Expression_Type expr_type);
00199 
00200   /// expr_returns_boolean returns 1 if <expr_type>, when evaluated, will
00201   /// return a string.
00202   int expr_returns_string (TAO_Expression_Type expr_type);
00203 
00204   TAO_Constraint_Validator (const TAO_Constraint_Validator&);
00205   TAO_Constraint_Validator& operator= (const TAO_Constraint_Validator&);
00206 };
00207 
00208 /**
00209  * @class TAO_Constraint_Evaluator
00210  *
00211  * @brief TAO_Constraint_Evaluator traverse a constraint expression
00212  * tree, and determines whether an offer fits the constraints
00213  * represented by the tree
00214  *
00215  * Using the Visitor pattern, the TAO_Constraint_Evaluator has
00216  * each node of the expression tree call back to it with the
00217  * method designated for its type. In that method, the visitor
00218  * will evaluate its operands and perform the operation
00219  * designated by that node's type, and return the result. Note:
00220  * the TAO_Constraint_Evaluator assumes the tree is semantically
00221  * correct, that is, the validate method on
00222  * TAO_Constraint_Validator return true. The only possible
00223  * evaluation time errors are a divide by a property whose value
00224  * is zero and undefined properties.
00225  */
00226 class TAO_Trading_Serv_Export TAO_Constraint_Evaluator : public TAO_Constraint_Visitor
00227 {
00228 public:
00229 
00230   /// Constructor.
00231   TAO_Constraint_Evaluator (void);
00232 
00233   /**
00234    * Evaluate returns 1 if the offer satisfies the constraints
00235    * represented by the the expression tree rooted at <root>, 0 if it
00236    * doesn't. If an error occurs during process, the constraint
00237    * automatically fails.
00238    */
00239   CORBA::Boolean evaluate_constraint (TAO_Constraint* root);
00240 
00241   /// The result of the preference evaluation is stored in result. The
00242   /// method returns 0 upon success, -1 upon failure.
00243   int evaluate_preference (TAO_Constraint* root,
00244                            TAO_Literal_Constraint& result);
00245 
00246   // = Visitor Methods
00247 
00248   virtual int visit_constraint (TAO_Unary_Constraint* constraint);
00249 
00250   virtual int visit_with (TAO_Unary_Constraint* unary_with);
00251   virtual int visit_min (TAO_Unary_Constraint* unary_min);
00252   virtual int visit_max (TAO_Unary_Constraint* unary_max);
00253   virtual int visit_first (TAO_Noop_Constraint* noop_first);
00254   virtual int visit_random (TAO_Noop_Constraint* noop_random);
00255 
00256   /**
00257    * Takes the logical and of the results of both operands. Note that
00258    * in the case where the left operand returns zero, the result is
00259    * immediately known.
00260    */
00261   virtual int visit_and (TAO_Binary_Constraint* boolean_and);
00262 
00263   /**
00264    * Takes the logical or of the results of both operands. Note that
00265    * in the case where the left operand returns one, the result is
00266    * immediately known.
00267    */
00268   virtual int visit_or (TAO_Binary_Constraint* boolean_or);
00269 
00270   /// Logically negates the value of the operand.
00271   virtual int visit_not (TAO_Unary_Constraint* unary_not);
00272 
00273   /// The property exists if its name is bound to a value in the
00274   /// <props_> map.
00275   virtual int visit_exist (TAO_Unary_Constraint* unary_exist);
00276 
00277   /// Mathematically negates the return value the operand.
00278   virtual int visit_unary_minus (TAO_Unary_Constraint* unary_minus);
00279 
00280   /// Add the results of evaluating the left and right operands.
00281   virtual int visit_add (TAO_Binary_Constraint* boolean_add);
00282 
00283   /// Subtract the results of evaluating the left and right operands.
00284   virtual int visit_sub (TAO_Binary_Constraint* boolean_sub);
00285 
00286   /// Multiply the results of evaluating the left and right operands.
00287   virtual int visit_mult (TAO_Binary_Constraint* boolean_mult);
00288 
00289   /// Divide the results of evaluating the left and right operands.
00290   virtual int visit_div (TAO_Binary_Constraint* boolean_div);
00291 
00292   /// Determines if the right operand is a substring of the left.
00293   virtual int visit_twiddle (TAO_Binary_Constraint* binary_twiddle);
00294 
00295   /// Determines if the sequence represented by the right operand
00296   /// contains the left operand.
00297   virtual int visit_in (TAO_Binary_Constraint* binary_in);
00298 
00299   // = Compare the results of evaluating left and right operands.
00300   virtual int visit_less_than (TAO_Binary_Constraint* boolean_lt);
00301   virtual int visit_less_than_equal (TAO_Binary_Constraint* boolean_lte);
00302   virtual int visit_greater_than (TAO_Binary_Constraint* boolean_gt);
00303   virtual int visit_greater_than_equal (TAO_Binary_Constraint* boolean_gte);
00304   virtual int visit_equal (TAO_Binary_Constraint* boolean_eq);
00305   virtual int visit_not_equal (TAO_Binary_Constraint* boolean_neq);
00306 
00307   /// Copy the value of the literal into the result container.
00308   virtual int visit_literal (TAO_Literal_Constraint* literal);
00309 
00310   /// Copy the value of the property into the result container.
00311   virtual int visit_property (TAO_Property_Constraint* literal);
00312 
00313 private:
00314 
00315   class TAO_Trading_Serv_Export Operand_Queue :
00316     public ACE_Unbounded_Queue <TAO_Literal_Constraint>
00317   // = TITLE
00318   // A queue adapter with methods to setting and getting operands
00319   // from the expression evaluation results.
00320   {
00321   public:
00322 
00323     Operand_Queue  (void);
00324 
00325     /// In a binary operation, obtain the left operand.
00326     TAO_Literal_Constraint& get_left_operand (void);
00327 
00328     /// In a binary operation, obtain the right operand.
00329     TAO_Literal_Constraint& get_right_operand (void);
00330 
00331     /// In a unary operation, obtain the only operand.
00332     TAO_Literal_Constraint& get_operand (void);
00333 
00334     /// Remove an operand from the queue.
00335     void dequeue_operand (void);
00336   };
00337 
00338   /// Method for performing a arithmetic or comparison operation.
00339   void do_the_op (int operation);
00340 
00341   /// Method for evaluating a binary operation.
00342   int visit_bin_op (TAO_Binary_Constraint* op, int operation);
00343 
00344   /// Determine if sequence contains <element>, a literal of the same
00345   /// simple type as <sequence_type>. Return 1 in this eventuality.
00346   CORBA::Boolean sequence_does_contain (CORBA::Any* sequence,
00347                                         TAO_Literal_Constraint& element);
00348 
00349   /// Disallow copying.
00350   TAO_Constraint_Evaluator (const TAO_Constraint_Evaluator&);
00351   TAO_Constraint_Evaluator& operator= (const TAO_Constraint_Evaluator&);
00352 
00353 protected:
00354 
00355   /// The map of property names to their values for a property.
00356   TAO_Lookup_Table props_;
00357 
00358   /// The result of a non_boolean operation.
00359   Operand_Queue queue_;
00360 };
00361 
00362 // Forward declaration
00363 template <class ELEMENT_TYPE> class TAO_Element_Equal;
00364 
00365 template<>
00366 class TAO_Element_Equal<CORBA::Short>
00367 {
00368 public:
00369   /// Calls the correct method on dyn_seq to extract the element type,
00370   /// then uses the appropriate form of equals comparison.
00371   int operator () (TAO_DynSequence_i& dyn_any,
00372                    CORBA::Short element) const;
00373 };
00374 
00375 template<>
00376 class TAO_Element_Equal<CORBA::UShort>
00377 {
00378 public:
00379   /// Calls the correct method on dyn_seq to extract the element type,
00380   /// then uses the appropriate form of equals comparison.
00381   int operator () (TAO_DynSequence_i& dyn_any,
00382                    CORBA::UShort element) const;
00383 };
00384 
00385 template<>
00386 class TAO_Element_Equal<CORBA::Long>
00387 {
00388 public:
00389   /// Calls the correct method on dyn_seq to extract the element type,
00390   /// then uses the appropriate form of equals comparison.
00391   int operator () (TAO_DynSequence_i& dyn_any,
00392                    CORBA::Long element) const;
00393 };
00394 
00395 template<>
00396 class TAO_Element_Equal<CORBA::ULong>
00397 {
00398 public:
00399   /// Calls the correct method on dyn_seq to extract the element type, then
00400   /// uses the appropriate form of equals comparison.
00401   int operator () (TAO_DynSequence_i& dyn_any,
00402                    CORBA::ULong element) const;
00403 
00404 };
00405 
00406 template<>
00407 class TAO_Element_Equal<CORBA::Float>
00408 {
00409 public:
00410   /// Calls the correct method on dyn_seq to extract the element type,
00411   /// then uses the appropriate form of equals comparison.
00412   int operator () (TAO_DynSequence_i& dyn_any,
00413                    CORBA::Float element) const;
00414 };
00415 
00416 template<>
00417 class TAO_Element_Equal<CORBA::Double>
00418 {
00419 public:
00420   /// Calls the correct method on dyn_seq to extract the element type,
00421   /// then uses the appropriate form of equals comparison.
00422   int operator () (TAO_DynSequence_i& dyn_any,
00423                    CORBA::Double element) const;
00424 };
00425 
00426 template<>
00427 class TAO_Element_Equal<CORBA::Boolean>
00428 {
00429 public:
00430   /// Calls the correct method on dyn_seq to extract the element type,
00431   /// then uses the appropriate form of equals comparison.
00432   int operator () (TAO_DynSequence_i& dyn_any,
00433                    CORBA::Boolean element) const;
00434 };
00435 
00436 template<>
00437 class TAO_Element_Equal<const char*>
00438 {
00439 public:
00440   /// Calls the correct method on dyn_seq to extract the element type,
00441   /// then uses the appropriate form of equals comparison.
00442   int operator () (TAO_DynSequence_i& dyn_any,
00443                    const char* element) const;
00444 };
00445 
00446 TAO_END_VERSIONED_NAMESPACE_DECL
00447 
00448 #include /**/ "ace/post.h"
00449 #endif /* CONSTRAINT_VISITORS_H */

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