Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes

TAO_Notify_Constraint_Visitor Class Reference

#include <Notify_Constraint_Visitors.h>

Inheritance diagram for TAO_Notify_Constraint_Visitor:
Inheritance graph
[legend]
Collaboration diagram for TAO_Notify_Constraint_Visitor:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 TAO_Notify_Constraint_Visitor (void)
 Constructor.
int bind_structured_event (const CosNotification::StructuredEvent &s_event)
 Put the event data into our hash map.
CORBA::Boolean evaluate_constraint (ETCL_Constraint *root)
virtual int visit_literal (ETCL_Literal_Constraint *)
virtual int visit_identifier (ETCL_Identifier *)
virtual int visit_union_value (ETCL_Union_Value *)
virtual int visit_union_pos (ETCL_Union_Pos *)
virtual int visit_component_pos (ETCL_Component_Pos *)
virtual int visit_component_assoc (ETCL_Component_Assoc *)
virtual int visit_component_array (ETCL_Component_Array *)
virtual int visit_special (ETCL_Special *)
virtual int visit_component (ETCL_Component *)
virtual int visit_dot (ETCL_Dot *)
virtual int visit_eval (ETCL_Eval *)
virtual int visit_default (ETCL_Default *)
virtual int visit_exist (ETCL_Exist *)
virtual int visit_unary_expr (ETCL_Unary_Expr *)
virtual int visit_binary_expr (ETCL_Binary_Expr *)
virtual int visit_preference (ETCL_Preference *)

Protected Types

enum  structured_event_field {
  FILTERABLE_DATA, HEADER, FIXED_HEADER, EVENT_TYPE,
  DOMAIN_NAME, TYPE_NAME, EVENT_NAME, VARIABLE_HEADER,
  REMAINDER_OF_BODY, EMPTY
}

Protected Member Functions

int visit_or (ETCL_Binary_Expr *)
int visit_and (ETCL_Binary_Expr *)
int visit_twiddle (ETCL_Binary_Expr *)
int visit_in (ETCL_Binary_Expr *)
int visit_binary_op (ETCL_Binary_Expr *binary_expr, int op_type)
CORBA::Boolean sequence_does_contain (const CORBA::Any *any, TAO_ETCL_Literal_Constraint &item)
CORBA::Boolean array_does_contain (const CORBA::Any *any, TAO_ETCL_Literal_Constraint &item)
CORBA::Boolean struct_does_contain (const CORBA::Any *any, TAO_ETCL_Literal_Constraint &item)
CORBA::Boolean union_does_contain (const CORBA::Any *any, TAO_ETCL_Literal_Constraint &item)
CORBA::Boolean any_does_contain (const CORBA::Any *any, TAO_ETCL_Literal_Constraint &item)
CORBA::Boolean simple_type_match (int expr_type, CORBA::TCKind tc_kind)

Protected Attributes

structured_event_field implicit_id_
 Storage for the type of implicit id the component has (if any).
ACE_Hash_Map_Manager
< ACE_CString,
structured_event_field,
ACE_Null_Mutex
implicit_ids_
ACE_Hash_Map_Manager
< ACE_CString, CORBA::Any,
ACE_Null_Mutex
filterable_data_
 Used to lookup names and values in the event's 'filterable_data' field.
ACE_Hash_Map_Manager
< ACE_CString, CORBA::Any,
ACE_Null_Mutex
variable_header_
 Used to lookup names and values in the event's 'variable_header' field.
CORBA::String_var domain_name_
CORBA::String_var type_name_
CORBA::String_var event_name_
CORBA::Any remainder_of_body_
 Storage for the structured_event's 'remainder_of_body' field.
ACE_Unbounded_Queue
< TAO_ETCL_Literal_Constraint
queue_
 The result of a non_boolean operation.
CORBA::Any_var current_value_
CORBA::String_var current_name_

Static Protected Attributes

static const size_t implicit_ids_size_ = 27
static const size_t filterable_data_size_ = 31
static const size_t variable_header_size_ = 31

Detailed Description

Definition at line 39 of file Notify_Constraint_Visitors.h.


Member Enumeration Documentation

Enumerator:
FILTERABLE_DATA 
HEADER 
FIXED_HEADER 
EVENT_TYPE 
DOMAIN_NAME 
TYPE_NAME 
EVENT_NAME 
VARIABLE_HEADER 
REMAINDER_OF_BODY 
EMPTY 

Definition at line 100 of file Notify_Constraint_Visitors.h.

    {
      FILTERABLE_DATA,
      HEADER,
      FIXED_HEADER,
      EVENT_TYPE,
      DOMAIN_NAME,
      TYPE_NAME,
      EVENT_NAME,
      VARIABLE_HEADER,
      REMAINDER_OF_BODY,
      EMPTY
    };


Constructor & Destructor Documentation

TAO_Notify_Constraint_Visitor::TAO_Notify_Constraint_Visitor ( void   ) 

Constructor.

Definition at line 22 of file Notify_Constraint_Visitors.cpp.

  : implicit_id_ (TAO_Notify_Constraint_Visitor::EMPTY),
    implicit_ids_(implicit_ids_size_),
    filterable_data_(filterable_data_size_),
    variable_header_(variable_header_size_)
{
  (void) this->implicit_ids_.bind (ACE_CString ("filterable_data",
    0,
    false),
    FILTERABLE_DATA);
  (void) this->implicit_ids_.bind (ACE_CString ("header",
    0,
    false),
    HEADER);
  (void) this->implicit_ids_.bind (ACE_CString ("remainder_of_body",
    0,
    false),
    REMAINDER_OF_BODY);
  (void) this->implicit_ids_.bind (ACE_CString ("fixed_header",
    0,
    false),
    FIXED_HEADER);
  (void) this->implicit_ids_.bind (ACE_CString ("variable_header",
    0,
    false),
    VARIABLE_HEADER);
  (void) this->implicit_ids_.bind (ACE_CString ("event_name",
    0,
    false),
    EVENT_NAME);
  (void) this->implicit_ids_.bind (ACE_CString ("event_type",
    0,
    false),
    EVENT_TYPE);
  (void) this->implicit_ids_.bind (ACE_CString ("domain_name",
    0,
    false),
    DOMAIN_NAME);
  (void) this->implicit_ids_.bind (ACE_CString ("type_name",
    0,
    false),
    TYPE_NAME);
}


Member Function Documentation

CORBA::Boolean TAO_Notify_Constraint_Visitor::any_does_contain ( const CORBA::Any any,
TAO_ETCL_Literal_Constraint item 
) [protected]

Definition at line 1398 of file Notify_Constraint_Visitors.cpp.

{
  const CORBA::Any *result = 0;
  *any >>= result;

  TAO_ETCL_Literal_Constraint element (const_cast<CORBA::Any *>(result));
  return item == element;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::array_does_contain ( const CORBA::Any any,
TAO_ETCL_Literal_Constraint item 
) [protected]

Definition at line 1261 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    CORBA::TypeCode_var type = any->type ();
    CORBA::TCKind kind = TAO_DynAnyFactory::unalias (type.in ());

    // The literal and the array elements must be
    // of the same simple type.
    CORBA::Boolean match =
      this->simple_type_match (item.expr_type (),
                               kind);

    if (!match)
      {
        return false;
      }

    TAO_DynArray_i dyn_array;
    dyn_array.init (*any);

    DynamicAny::AnySeq_var any_seq = dyn_array.get_elements ();

    CORBA::ULong length = any_seq->length ();

    for (CORBA::ULong i = 0; i < length; ++i)
      {
        TAO_ETCL_Literal_Constraint element (&any_seq[i]);

        if (item == element)
          {
            return true;
          }
      }
  }
  catch (const CORBA::Exception&)
  {
    return false;
  }

  return false;
}

int TAO_Notify_Constraint_Visitor::bind_structured_event ( const CosNotification::StructuredEvent s_event  ) 

Put the event data into our hash map.

Definition at line 67 of file Notify_Constraint_Visitors.cpp.

{
  // The two sequences contained in a structured event are
  // copied into hash tables so iteration is done only once.

  CORBA::ULong length = s_event.filterable_data.length ();
  CORBA::ULong index = 0;

  for (index = 0; index < length; ++index)
  {
    ACE_CString name_str (s_event.filterable_data[index].name, 0, false);

    int status =
      this->filterable_data_.bind (
        name_str,
        s_event.filterable_data[index].value
        );

    if (status != 0)
      return -1;
  }

  length = s_event.header.variable_header.length ();

  for (index = 0; index < length; ++index)
  {
    ACE_CString name_str (s_event.header.variable_header[index].name, 0, false);

    int status =
      this->variable_header_.bind (
        name_str,
        s_event.header.variable_header[index].value
        );

    if (status != 0)
      return -1;
  }

  this->domain_name_ =
    CORBA::string_dup (s_event.header.fixed_header.event_type.domain_name);

  this->type_name_ =
    CORBA::string_dup (s_event.header.fixed_header.event_type.type_name);

  this->event_name_ =
    CORBA::string_dup (s_event.header.fixed_header.event_name);

  this->remainder_of_body_ = s_event.remainder_of_body;

  return 0;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::evaluate_constraint ( ETCL_Constraint root  ) 

Returns true if the event satisfies the constraint represented by the the expression tree rooted at root, false if it doesn't. If an error occurs during the process, the traversal automatically fails.

Definition at line 120 of file Notify_Constraint_Visitors.cpp.

{
  CORBA::Boolean result = 0;
  this->queue_.reset ();

  // Evaluate the constraint in root_;
  if (root != 0)
    {
      if ((root->accept (this) == 0) && (! this->queue_.is_empty ()))
        {
          TAO_ETCL_Literal_Constraint top;
          this->queue_.dequeue_head (top);
          result = (CORBA::Boolean) top;
        }
    }

  // If a property couldn't be evaluated we must return 0.
  return result;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::sequence_does_contain ( const CORBA::Any any,
TAO_ETCL_Literal_Constraint item 
) [protected]

Definition at line 1209 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    CORBA::TypeCode_var type = any->type ();
    CORBA::TypeCode_var base_type =
      TAO_DynAnyFactory::strip_alias (type.in ());
    CORBA::TypeCode_var content_type =
      base_type->content_type ();
    CORBA::TCKind kind =
      TAO_DynAnyFactory::unalias (content_type.in ());

    // The literal and the array elements must be
    // of the same simple type.
    CORBA::Boolean match =
      this->simple_type_match (item.expr_type (),
                               kind);

    if (!match)
      {
        return false;
      }

    TAO_DynSequence_i dyn_seq;
    dyn_seq.init (*any);

    DynamicAny::AnySeq_var any_seq = dyn_seq.get_elements ();

    CORBA::ULong length = any_seq->length ();

    for (CORBA::ULong i = 0; i < length; ++i)
      {
        TAO_ETCL_Literal_Constraint element (&any_seq[i]);

        if (item == element)
          {
            return true;
          }
      }
  }
  catch (const CORBA::Exception&)
  {
    return false;
  }

  return false;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::simple_type_match ( int  expr_type,
CORBA::TCKind  tc_kind 
) [protected]

Utility function to compare a TAO_ETCL_Literal_Constraint type and a type code.

Definition at line 1411 of file Notify_Constraint_Visitors.cpp.

{
  switch (expr_type)
  {
  case ETCL_STRING:
    if (tc_kind != CORBA::tk_string)
      {
        return false;
      }
    break;
  case ETCL_DOUBLE:
    if (tc_kind != CORBA::tk_double && tc_kind != CORBA::tk_float)
      {
        return false;
      }
    break;
  case ETCL_INTEGER:
  case ETCL_SIGNED:
    if (tc_kind != CORBA::tk_short
        && tc_kind != CORBA::tk_long
        && tc_kind != CORBA::tk_longlong)
      {
        return false;
      }
    break;
  case ETCL_UNSIGNED:
    if (tc_kind != CORBA::tk_ushort
        && tc_kind != CORBA::tk_ulong
        && tc_kind != CORBA::tk_ulonglong)
      {
        return false;
      }
    break;
  case ETCL_BOOLEAN:
    if (tc_kind != CORBA::tk_boolean)
      {
        return false;
      }
    break;
  default:
    return false;
  }
  
  return true;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::struct_does_contain ( const CORBA::Any any,
TAO_ETCL_Literal_Constraint item 
) [protected]

Definition at line 1308 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    TAO_DynStruct_i dyn_struct;
    dyn_struct.init (*any);

    DynamicAny::NameValuePairSeq_var members =
      dyn_struct.get_members ();

    CORBA::ULong length = members->length ();
    CORBA::TypeCode_var tc;
    CORBA::TCKind kind;

    for (CORBA::ULong i = 0; i < length; ++i)
      {
        tc = members[i].value.type ();
        kind = TAO_DynAnyFactory::unalias (tc.in ());

        // The literal and the struct member must be
        // of the same simple type.
        CORBA::Boolean match =
          this->simple_type_match (item.expr_type (),
                                   kind);

        if (!match)
          {
            continue;
          }

        TAO_ETCL_Literal_Constraint element (&members[i].value);

        if (item == element)
          {
            return true;
          }
      }
  }
  catch (const CORBA::Exception&)
  {
    return false;
  }

  return false;
}

CORBA::Boolean TAO_Notify_Constraint_Visitor::union_does_contain ( const CORBA::Any any,
TAO_ETCL_Literal_Constraint item 
) [protected]

Definition at line 1358 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    TAO_DynUnion_i dyn_union;
    dyn_union.init (*any);

    DynamicAny::DynAny_var cc =
      dyn_union.current_component ();

    CORBA::Any_var member = cc->to_any ();

    CORBA::TypeCode_var tc = member->type ();
    CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());

    // The literal and the union member must be
    // of the same simple type.
    CORBA::Boolean match =
      this->simple_type_match (item.expr_type (),
                               kind);

    if (!match)
      {
        return false;
      }

    TAO_ETCL_Literal_Constraint element (&member.inout ());

    return (item == element);
  }
  catch (const CORBA::Exception&)
  {
    return false;
  }
}

int TAO_Notify_Constraint_Visitor::visit_and ( ETCL_Binary_Expr binary  )  [protected]

Definition at line 980 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  CORBA::Boolean result = false;
  ETCL_Constraint *lhs = binary->lhs ();

  if (lhs->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint lhs_result;
      this->queue_.dequeue_head (lhs_result);
      result = (CORBA::Boolean) lhs_result;

      // Short-circuiting AND.
      if (result == true)
        {
          ETCL_Constraint *rhs = binary->rhs ();

          if (rhs->accept (this) == 0)
          {
            TAO_ETCL_Literal_Constraint rhs_result;
            this->queue_.dequeue_head (rhs_result);
            result = (CORBA::Boolean) rhs_result;
            return_value = 0;
          }
        }
      else
        {
          return_value = 0;
        }
    }

  if (return_value == 0)
    {
      this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_binary_expr ( ETCL_Binary_Expr binary_expr  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 905 of file Notify_Constraint_Visitors.cpp.

{
  int bin_op_type = binary_expr->type ();

  switch (bin_op_type)
  {
  case ETCL_OR:
    return this->visit_or (binary_expr);
  case ETCL_AND:
    return this->visit_and (binary_expr);
  case ETCL_LT:
  case ETCL_LE:
  case ETCL_GT:
  case ETCL_GE:
  case ETCL_EQ:
  case ETCL_NE:
  case ETCL_PLUS:
  case ETCL_MINUS:
  case ETCL_MULT:
  case ETCL_DIV:
    return this->visit_binary_op (binary_expr, bin_op_type);
  case ETCL_TWIDDLE:
    return this->visit_twiddle (binary_expr);
  case ETCL_IN:
    return this->visit_in (binary_expr);
  default:
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_binary_op ( ETCL_Binary_Expr binary_expr,
int  op_type 
) [protected]

Definition at line 1020 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  ETCL_Constraint *lhs = binary->lhs ();
  CORBA::Boolean result = false;

  // Perform an operation on the results of evaluating the left and
  // right branches of this subtree.
  if (lhs->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint left_operand;
      this->queue_.dequeue_head (left_operand);
      ETCL_Constraint *rhs = binary->rhs ();

      if (rhs->accept (this) == 0)
        {
          TAO_ETCL_Literal_Constraint right_operand;
          this->queue_.dequeue_head (right_operand);
          return_value = 0;

          switch (op_type)
          {
          case ETCL_LT:
            result = left_operand < right_operand;
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_LE:
            // result = left_operand <= right_operand; // Compile error on LynxOS
            result = left_operand.operator<= (right_operand);
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_GT:
            // result = left_operand > right_operand; // Compile error on LynxOS
            result = left_operand.operator> (right_operand);
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_GE:
            //result = left_operand >= right_operand; // Compile error on LynxOS
            result = left_operand.operator>= (right_operand);
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_EQ:
            result = left_operand == right_operand;
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_NE:
            //result = left_operand != right_operand; // Compile error on LynxOS
            result = left_operand.operator!= (right_operand);
            this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
            break;
          case ETCL_PLUS:
            this->queue_.enqueue_head (left_operand + right_operand);
            break;
          case ETCL_MINUS:
            this->queue_.enqueue_head (left_operand - right_operand);
            break;
          case ETCL_MULT:
            this->queue_.enqueue_head (left_operand * right_operand);
            break;
          case ETCL_DIV:
            this->queue_.enqueue_head (left_operand / right_operand);
            break;
          default:
            return_value = -1;
          }
        }
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_component ( ETCL_Component component  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 638 of file Notify_Constraint_Visitors.cpp.

{
  ETCL_Constraint *nested = component->component ();
  ETCL_Identifier *identifier = component->identifier ();
  ACE_CString component_name (identifier->value (),
                              0,
                              false);
  CORBA::Any *any_ptr = 0;
  int result =
    this->implicit_ids_.find (component_name, this->implicit_id_);

  if (result != 0)
    {
      this->implicit_id_ = TAO_Notify_Constraint_Visitor::EMPTY;
    }

  // If this component has no sub-component, only an identifier, then
  // we just visit the identifier, which puts a literal on the queue
  // to be handled upon returning from this method call.  If there is
  // a sub-component, we store the literal's value in our member _var
  // for possible examination at a more nested level, and visit the
  // sub-component. If the identifier matches one of the nested field
  // names in CosNotification::StructuredEvent, we just visit the
  // nested component, if any.
  if (this->implicit_id_ == TAO_Notify_Constraint_Visitor::EMPTY)
    {
      ACE_NEW_RETURN (any_ptr,
                      CORBA::Any,
                      -1);

      if (nested == 0)
        {
          // If this is the end of the line, we put the component name
          // into current_value_ so visit_exist can use it.
          (*any_ptr) <<= component_name.c_str ();
          this->current_value_ = any_ptr;
          return identifier->accept (this);
        }
      else
        {
          int result = identifier->accept (this);

          if (result != 0)
            {
              return result;
            }

          TAO_ETCL_Literal_Constraint id;
          this->queue_.dequeue_head (id);
                          
          any_ptr->replace (id);
          any_ptr->impl ()->_add_ref ();
          this->current_value_ = any_ptr;
        }
    }

  if (nested != 0)
    {
      return nested->accept (this);
    }
  else
    {
      switch (this->implicit_id_)
      {
      case TYPE_NAME:
        {
          TAO_ETCL_Literal_Constraint tn (this->type_name_.in ());
          this->queue_.enqueue_head (tn);
          return 0;
        }
      case EVENT_NAME:
        {
          TAO_ETCL_Literal_Constraint en (this->event_name_.in ());
          this->queue_.enqueue_head (en);
          return 0;
        }
      case DOMAIN_NAME:
        {
          TAO_ETCL_Literal_Constraint dn (this->domain_name_.in ());
          this->queue_.enqueue_head (dn);
          return 0;
        }
      case REMAINDER_OF_BODY:
        {
          TAO_ETCL_Literal_Constraint rob (&this->remainder_of_body_);
          this->queue_.enqueue_head (rob);
          return 0;
        }
        // The above cases are the leaves of the
        // CosNotification::StructuredEvent "tree". Anything else and we
        // should have a nested component. otherwise, it's an error.
      default:
        return -1;
      }
    }
}

int TAO_Notify_Constraint_Visitor::visit_component_array ( ETCL_Component_Array array  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 483 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    // If we are here (from visit_component) the Any containing the
    // component as found in filterable_data_ will be in
    // current_value_.
    CORBA::TypeCode_var tc = this->current_value_->type ();
    CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());

    DynamicAny::DynAny_var member;
    CORBA::Boolean success = 0;
    CORBA::ULong slot = (CORBA::ULong) *array->integer ();

    switch (kind)
    {
    case CORBA::tk_array:
      {
        TAO_DynEnum_i dyn_array;
        dyn_array.init (this->current_value_.in ());
        success = dyn_array.seek (slot);

        if (!success)
          {
            return -1;
          }

        member = dyn_array.current_component ();
        break;
      }
    case CORBA::tk_sequence:
      {
        TAO_DynStruct_i dyn_sequence;
        dyn_sequence.init (this->current_value_.in ());
        success = dyn_sequence.seek (slot);

        if (!success)
          {
            return -1;
          }

        member =dyn_sequence.current_component ();
        break;
      }
      // Enums and sequences are the only two cases handled
      // by Component_Array.
    default:
      return -1;
    }

    CORBA::Any_var value = member->to_any ();
    ETCL_Constraint *comp = array->component ();

    if (comp == 0)
      {
        TAO_ETCL_Literal_Constraint result (value.ptr ());
        this->queue_.enqueue_head (result);
        return 0;
      }
    else
      {
        this->current_value_ = value._retn ();
        return comp->accept (this);
      }
  }
  catch (const CORBA::Exception&)
  {
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_component_assoc ( ETCL_Component_Assoc assoc  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 423 of file Notify_Constraint_Visitors.cpp.

{
  CORBA::Any any;
  ACE_CString name (assoc->identifier ()->value (),
                    0,
                    false);

  switch (this->implicit_id_)
  {
  case FILTERABLE_DATA:
    if (this->filterable_data_.find (name, any) != 0 || any.impl () == 0)
      {
        return -1;
      }
    break;
  case VARIABLE_HEADER:
    if (this->variable_header_.find (name, any) != 0|| any.impl () == 0)
      {
        return -1;
      }
    break;
    // Only the sequence members of CosNotification::StructuredEvent
    // can be treated as associative arrays.
  default:
    return -1;
  }

  ETCL_Constraint *comp = assoc->component ();
  CORBA::Any *any_ptr = 0;

  if (comp == 0)
    {
      TAO_ETCL_Literal_Constraint result (&any);
      this->queue_.enqueue_head (result);

      // If we're at the end of the line, put the name into
      // current_value_ so visit_exist can use it.
      ACE_NEW_RETURN (any_ptr,
                      CORBA::Any,
                      -1);
                      
      (*any_ptr) <<= name.c_str ();
      this->current_value_ = any_ptr;

      return 0;
    }
  else
    {
      ACE_NEW_RETURN (any_ptr,
                      CORBA::Any (any),
                      -1);
                      
      this->current_value_ = any_ptr;
      return comp->accept (this);
    }
}

int TAO_Notify_Constraint_Visitor::visit_component_pos ( ETCL_Component_Pos pos  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 348 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    // If we are here (from visit_component) the Any containing the
    // component as found in filterable_data_ will be in current_value_.
    CORBA::TypeCode_var tc = this->current_value_->type ();
    CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());

    DynamicAny::DynAny_var member;
    CORBA::Boolean success = 0;
    CORBA::ULong slot = (CORBA::ULong) *pos->integer ();

    switch (kind)
    {
    case CORBA::tk_enum:
      {
        TAO_DynEnum_i dyn_enum;
        dyn_enum.init (this->current_value_.in ());
        success = dyn_enum.seek (slot);

        if (!success)
          {
            return -1;
          }

        member = dyn_enum.current_component ();
        break;
      }
    case CORBA::tk_struct:
      {
        TAO_DynStruct_i dyn_struct;
        dyn_struct.init (this->current_value_.in ());
        success = dyn_struct.seek (slot);

        if (!success)
          {
            return -1;
          }

        member = dyn_struct.current_component ();
        break;
      }
      // @@@ (JP) I think enums and structs are the only two cases
      // handled by Component_Pos, since arrays and sequences are
      // handled by Component_Array, and unions are handled by
      // Union_Pos.
    default:
      return -1;
    }

    CORBA::Any_var value = member->to_any ();
    ETCL_Constraint *comp = pos->component ();

    if (comp == 0)
      {
        TAO_ETCL_Literal_Constraint result (value.ptr ());
        this->queue_.enqueue_head (result);
        return 0;
      }
    else
      {
        this->current_value_ = value._retn ();
        return comp->accept (this);
      }
  }
  catch (const CORBA::Exception&)
  {
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_default ( ETCL_Default def  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 754 of file Notify_Constraint_Visitors.cpp.

{
  ETCL_Constraint *comp = def->component ();

  if (comp == 0)
    {
      return -1;
    }

  if (comp->accept (this) != 0)
    {
      return -1;
    }

  try
  {
    CORBA::TypeCode_var tc = this->current_value_->type ();

    // If the current member is not a union, this call will throw
    // BadKind and the catch block will return -1.
    CORBA::Long default_index = tc->default_index ();

    // No default index.
    if (default_index == -1)
    {
      TAO_ETCL_Literal_Constraint result (false);
      this->queue_.enqueue_head (result);
      return 0;
    }

    // Okay, there's a default index, but is it active?
    TAO_ETCL_Literal_Constraint disc_value;
    this->queue_.dequeue_head (disc_value);
    TAO_ETCL_Literal_Constraint default_index_value (default_index);
    
    return (disc_value == default_index_value);
  }
  catch (const CORBA::Exception&)
  {
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_dot ( ETCL_Dot dot  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 738 of file Notify_Constraint_Visitors.cpp.

{
  // If we are here, we know we're headed for a more nested
  // level, so we just visit it, there's nothing else in this
  // constraint.
  return dot->component ()->accept (this);
}

int TAO_Notify_Constraint_Visitor::visit_eval ( ETCL_Eval eval  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 747 of file Notify_Constraint_Visitors.cpp.

{
  // Nothing to do but visit the contained component.
  return eval->component ()->accept (this);
}

int TAO_Notify_Constraint_Visitor::visit_exist ( ETCL_Exist exist  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 798 of file Notify_Constraint_Visitors.cpp.

{
  ETCL_Constraint *component = exist->component ();

  if (component->accept (this) == 0)
    {
      const char *value = 0;
      CORBA::Boolean result = 0;

      // For the two cases below, we don't want the item at the top of
      // the queue, because it's the result of a hash table
      // lookup. For an existence test, we want the key value, which
      // is stored in the current_value_ member.
      if (this->implicit_id_ == FILTERABLE_DATA
          || this->implicit_id_ == VARIABLE_HEADER)
        {
          this->current_value_ >>= value;
        }
      else if (this->implicit_id_ == EMPTY)
        {
          // If the implicit id is empty, then we must default
          // it to the filterable data and set up the value pointer.
          
          ETCL_Identifier* ident =
            dynamic_cast<ETCL_Identifier*> (component);
            
          if (ident != 0)
            {
              this->implicit_id_ = FILTERABLE_DATA;
              value = ident->value ();
            }
        }

      switch (this->implicit_id_)
      {
      case FILTERABLE_DATA:
        result =
          (this->filterable_data_.find (ACE_CString (value, 0, false)) == 0);
        break;
      case VARIABLE_HEADER:
        result =
          (this->variable_header_.find (ACE_CString (value, 0, false)) == 0);
        break;
      case TYPE_NAME:
        result = (this->type_name_.in () != 0);
        break;
      case EVENT_NAME:
        result = (this->event_name_.in () != 0);
        break;
      case DOMAIN_NAME:
        result = (this->domain_name_.in () != 0);
        break;
        // Anything other than the above cases is an error.
      default:
        return -1;
      }

      this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));

      return 0;
    }

  return -1;
}

int TAO_Notify_Constraint_Visitor::visit_identifier ( ETCL_Identifier ident  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 151 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  const char *name = ident->value ();
  ACE_CString key (name, 0, false);

  CORBA::Any any;

  if (this->filterable_data_.find (key, any) == 0)
    {
      if (any.impl () != 0)
        {
          this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (&any));
          return_value = 0;
        }
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_in ( ETCL_Binary_Expr binary  )  [protected]

Definition at line 1121 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  ETCL_Constraint *lhs = binary->lhs ();

  // Determine if the left operand is contained in the right.
  if (lhs->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint left;
      this->queue_.dequeue_head (left);

      ETCL_Constraint *rhs = binary->rhs ();

      if (rhs->accept (this) == 0)
        {
          TAO_ETCL_Literal_Constraint bag;
          this->queue_.dequeue_head (bag);

          if (bag.expr_type () == ETCL_COMPONENT)
            {
              CORBA::Any_ptr any_ptr = 0;
              ACE_NEW_RETURN (any_ptr,
                              CORBA::Any,
                              -1);
                              
              CORBA::Any_var component = any_ptr;
              component->replace (bag);
              component->impl ()->_add_ref ();
              CORBA::TCKind kind = CORBA::tk_null;

              try
              {
                CORBA::TypeCode_var tc = component->type ();
                kind = TAO_DynAnyFactory::unalias (tc.in ());
              }
              catch (const CORBA::Exception&)
              {
                return return_value;
              }

              CORBA::Boolean result = 0;

              switch (kind)
              {
              case CORBA::tk_sequence:
                result = this->sequence_does_contain (&component.in (),
                                                      left);
                break;
              case CORBA::tk_array:
                result = this->array_does_contain (&component.in (),
                                                   left);
                break;
              case CORBA::tk_struct:
                result = this->struct_does_contain (&component.in (),
                                                    left);
                break;
              case CORBA::tk_union:
                result = this->union_does_contain (&component.in (),
                                                   left);
                break;
              case CORBA::tk_any:
                result = this->any_does_contain (&component.in (),
                                                 left);
                break;
              default:
                return return_value;
              }

              this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
              return_value = 0;
            }
        }
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_literal ( ETCL_Literal_Constraint literal  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 141 of file Notify_Constraint_Visitors.cpp.

{
  TAO_ETCL_Literal_Constraint lit (literal);
  this->queue_.enqueue_head (lit);
  return 0;
}

int TAO_Notify_Constraint_Visitor::visit_or ( ETCL_Binary_Expr binary  )  [protected]

Definition at line 938 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  CORBA::Boolean result = false;
  ETCL_Constraint *lhs = binary->lhs ();

  if (lhs->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint lhs_result;
      this->queue_.dequeue_head (lhs_result);
      result = (CORBA::Boolean) lhs_result;

      // Short-circuiting OR.
      if (result == 0)
        {
          ETCL_Constraint *rhs = binary->rhs ();

          if (rhs->accept (this) == 0)
            {
              TAO_ETCL_Literal_Constraint rhs_result;
              this->queue_.dequeue_head (rhs_result);
              result = (CORBA::Boolean) rhs_result;
              return_value = 0;
            }
        }
    else
      {
        return_value = 0;
      }
  }

  if (return_value == 0)
    {
      this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_preference ( ETCL_Preference  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 1199 of file Notify_Constraint_Visitors.cpp.

{
  // According to OMG 00-06-20 section 2.4.1, the Notification Service
  // does not use the preference operators. The method must be here
  // because it is called by the ETCL node, which may be used by other
  // CORBA services that do use the preference operators.
  return -1;
}

int TAO_Notify_Constraint_Visitor::visit_special ( ETCL_Special special  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 557 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    CORBA::TypeCode_var tc = this->current_value_->type ();
    tc = TAO_DynAnyFactory::strip_alias (tc.in ());
    CORBA::TCKind kind = tc->kind ();

    switch (special->type ())
    {
    case ETCL_LENGTH:
      {
        CORBA::ULong length;

        switch (kind)
        {
        case CORBA::tk_sequence:
          {
            TAO_DynSequence_i dyn_seq;
            dyn_seq.init (current_value_.in());

            DynamicAny::AnySeq_var any_seq =
              dyn_seq.get_elements ();

            length = any_seq->length ();
          }
          break;
        case CORBA::tk_array:
          length = tc->length ();
          break;
        default:
          return -1;
        }

        TAO_ETCL_Literal_Constraint lit (length);
        this->queue_.enqueue_head (lit);
        return 0;
      }
    case ETCL_DISCRIMINANT:
      {
        // If the TCKind is not a union, the call to init() will
        // raise an exception, and the catch block will return -1;
        TAO_DynUnion_i dyn_union;
        dyn_union.init (this->current_value_.in ());

        DynamicAny::DynAny_var disc =
          dyn_union.get_discriminator ();

        CORBA::Any_var disc_any = disc->to_any ();

        TAO_ETCL_Literal_Constraint lit (disc_any.ptr ());
        this->queue_.enqueue_head (lit);
        return 0;
      }
    case ETCL_TYPE_ID:
      {
        const char *name = tc->name ();

        TAO_ETCL_Literal_Constraint lit (name);
        this->queue_.enqueue_head (lit);
        return 0;
      }
    case ETCL_REPOS_ID:
      {
        const char *id = tc->id ();

        TAO_ETCL_Literal_Constraint lit (id);
        this->queue_.enqueue_head (lit);
        return 0;
      }
    default:
      return -1;
    }
  }
  catch (const CORBA::Exception&)
  {
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_twiddle ( ETCL_Binary_Expr binary  )  [protected]

Definition at line 1093 of file Notify_Constraint_Visitors.cpp.

{
  int return_value = -1;
  ETCL_Constraint *lhs = binary->lhs ();

  // Determine if the left operand is a substring of the right.
  if (lhs->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint left;
      this->queue_.dequeue_head (left);
      ETCL_Constraint *rhs = binary->rhs ();

      if (rhs->accept (this) == 0)
        {
          TAO_ETCL_Literal_Constraint right;
          this->queue_.dequeue_head (right);
          CORBA::Boolean result =
            (ACE_OS::strstr ((const char *) right,
                             (const char *) left) != 0);
          this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
          return_value = 0;
        }
    }

  return return_value;
}

int TAO_Notify_Constraint_Visitor::visit_unary_expr ( ETCL_Unary_Expr unary_expr  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 864 of file Notify_Constraint_Visitors.cpp.

{
  ETCL_Constraint *subexpr = unary_expr->subexpr ();

  if (subexpr->accept (this) == 0)
    {
      TAO_ETCL_Literal_Constraint subexpr_result;
      CORBA::Boolean result = false;
      int op_type = unary_expr->type ();

      switch (op_type)
      {
      case ETCL_NOT:
        this->queue_.dequeue_head (subexpr_result);
        result = ! (CORBA::Boolean) subexpr_result;
        this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
        return 0;
      case ETCL_MINUS:
        // The leading '-' was parsed separately, so we have to pull
        // the literal constraint off the queue, apply the class' own
        // unary minus operator, and put it back.
        this->queue_.dequeue_head (subexpr_result);
        this->queue_.enqueue_head (-subexpr_result);
        return 0;
      case ETCL_PLUS:
        // Leave the literal constraint on the queue. The leading
        // '+' was just syntactic sugar - no action is necessary.
        return 0;
      default:
        // The parser should never construct a ETCL_Unary_Constraint
        // behind any operators except the above three.
        return -1;
      }
    }

  return -1;
}

int TAO_Notify_Constraint_Visitor::visit_union_pos ( ETCL_Union_Pos union_pos  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 205 of file Notify_Constraint_Visitors.cpp.

{
  try
  {
    if (union_pos->union_value ()->accept (this) == 0)
      {
        TAO_ETCL_Literal_Constraint disc_val;
        this->queue_.dequeue_head (disc_val);

        TAO_DynUnion_i dyn_union;
        dyn_union.init (this->current_value_.in ());

        CORBA::TypeCode_var tc = this->current_value_->type ();

        switch (disc_val.expr_type ())
        {
        case ETCL_INTEGER:
        case ETCL_SIGNED:
        case ETCL_UNSIGNED:
          {
            CORBA::Any disc_any;
            CORBA::TypeCode_var disc_tc =
              tc->discriminator_type ();
            CORBA::TCKind disc_kind =
              TAO_DynAnyFactory::unalias (disc_tc.in ());

            switch (disc_kind)
            {
            case CORBA::tk_boolean:
              disc_any <<= CORBA::Any::from_boolean ((CORBA::Boolean) disc_val);
              break;
            case CORBA::tk_short:
              disc_any <<= (CORBA::Short) ((CORBA::Long) disc_val);
              break;
            case CORBA::tk_ushort:
              disc_any <<= (CORBA::UShort) ((CORBA::ULong) disc_val);
              break;
            case CORBA::tk_long:
              disc_any <<= (CORBA::Long) disc_val;
              break;
            case CORBA::tk_ulong:
              disc_any <<= (CORBA::ULong) disc_val;
              break;
            case CORBA::tk_enum:
              {
                TAO_OutputCDR cdr;
                cdr.write_ulong ((CORBA::ULong) disc_val);
                TAO_InputCDR in_cdr (cdr);
                TAO::Unknown_IDL_Type *unk = 0;
                ACE_NEW_RETURN (unk,
                                TAO::Unknown_IDL_Type (disc_tc.in (),
                                in_cdr),
                                -1);

                disc_any.replace (unk);
                break;
              }
              // @@@ (JP) I don't think ETCL handles 64-bit
              // integers at this point, and I also think that
              // chars and/or wchars will just come out in the
              // constraint as (w)strings of length 1.
            case CORBA::tk_longlong:
            case CORBA::tk_ulonglong:
            case CORBA::tk_char:
            case CORBA::tk_wchar:
            default:
              return -1;
            }

            DynamicAny::DynAny_var dyn_any =
              TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any &> (
                disc_tc.in (),
                disc_any);
            dyn_union.set_discriminator (dyn_any.in ());
            DynamicAny::DynAny_var u_member =
              dyn_union.member ();
            this->current_value_ =
              u_member->to_any ();

            break;
          }
        case ETCL_STRING:
          {
            const char *name = (const char *) disc_val;
            CORBA::ULong count = tc->member_count ();

            const char *member_name = 0;
            CORBA::ULong i = 0;

            for (i = 0; i < count; ++i)
              {
                member_name = tc->member_name (i);

                if (ACE_OS::strcmp (name, member_name) == 0)
                  {
                    break;
                  }
              }

            // If there's no match, member_label will throw
            // CORBA::TypeCode::Bounds and the catch block will
            // return -1;
            this->current_value_ = tc->member_label (i);

            break;
          }
          // The ETCL_Union_Value that was put on the queue
          // shouldn't have any other type.
        default:
          return -1;
        }

        ETCL_Constraint *nested = union_pos->component ();

        // If there's no nested component, then we just want the
        // union member value on the queue. Otherwise, we want
        // the member value in current_value_ while we visit
        // the nested component.
        if (nested == 0)
          {
            TAO_ETCL_Literal_Constraint lit (this->current_value_.ptr ());
            this->queue_.enqueue_head (lit);
            return 0;
          }
        else
          {
            return nested->accept (this);
          }
      }
    else
      {
        return -1;
      }
  }
  catch (const CORBA::Exception&)
  {
    return -1;
  }
}

int TAO_Notify_Constraint_Visitor::visit_union_value ( ETCL_Union_Value union_value  )  [virtual]

Reimplemented from ETCL_Constraint_Visitor.

Definition at line 172 of file Notify_Constraint_Visitors.cpp.

{
  switch (union_value->sign ())
  {
    case 0:
      {
        TAO_ETCL_Literal_Constraint lit (union_value->string ());
        this->queue_.enqueue_head (lit);
      }
      break;
    case -1:
      {
        CORBA::Long value = -(*union_value->integer ());
        TAO_ETCL_Literal_Constraint lit (value);
        this->queue_.enqueue_head (lit);
      }
      break;
    case 1:
      {
        TAO_ETCL_Literal_Constraint lit (union_value->integer ());
        this->queue_.enqueue_head (lit);
      }
      break;
    default:
      return -1;
  }

  return 0;
}


Member Data Documentation

Holder for a string name in the event fields fixed_header, variable_header, or filterable_data.

Definition at line 163 of file Notify_Constraint_Visitors.h.

Holder for a value found in the event fields filterable_data, variable_header or remainder_of_body.

Definition at line 159 of file Notify_Constraint_Visitors.h.

Storage for string names under the structured event's 'fixed_header' field.

Definition at line 147 of file Notify_Constraint_Visitors.h.

Definition at line 149 of file Notify_Constraint_Visitors.h.

Used to lookup names and values in the event's 'filterable_data' field.

Definition at line 135 of file Notify_Constraint_Visitors.h.

const size_t TAO_Notify_Constraint_Visitor::filterable_data_size_ = 31 [static, protected]

Size of filterable_data_ hash map.

Todo:
define inline once VC6 support is deprecated.

Definition at line 131 of file Notify_Constraint_Visitors.h.

Storage for the type of implicit id the component has (if any).

Definition at line 115 of file Notify_Constraint_Visitors.h.

Lookup table for the implicit ids, to avoid string comparisons in derived visitors.

Definition at line 127 of file Notify_Constraint_Visitors.h.

const size_t TAO_Notify_Constraint_Visitor::implicit_ids_size_ = 27 [static, protected]

Size of implicit_ids_ hash map.

Note:
A fixed set of 9 keys are stored in this map. In the absence of a minimal perfect hash, ACE's default hash_pjw() and a hash size of 27 ensures each element is hashed to a unique bucket.
Todo:
define inline once VC6 support is deprecated.

Definition at line 122 of file Notify_Constraint_Visitors.h.

The result of a non_boolean operation.

Definition at line 155 of file Notify_Constraint_Visitors.h.

Storage for the structured_event's 'remainder_of_body' field.

Definition at line 152 of file Notify_Constraint_Visitors.h.

Definition at line 148 of file Notify_Constraint_Visitors.h.

Used to lookup names and values in the event's 'variable_header' field.

Definition at line 143 of file Notify_Constraint_Visitors.h.

const size_t TAO_Notify_Constraint_Visitor::variable_header_size_ = 31 [static, protected]

Size of variable_header_ hash map.

Todo:
define inline once VC6 support is deprecated.

Definition at line 139 of file Notify_Constraint_Visitors.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines