00001
00002
00003 #include "orbsvcs/Notify/Notify_Constraint_Visitors.h"
00004
00005 #include "ace/ETCL/ETCL_y.h"
00006
00007 #include "tao/ETCL/TAO_ETCL_Constraint.h"
00008
00009 #include "tao/DynamicAny/DynArray_i.h"
00010 #include "tao/DynamicAny/DynSequence_i.h"
00011 #include "tao/DynamicAny/DynStruct_i.h"
00012 #include "tao/DynamicAny/DynUnion_i.h"
00013 #include "tao/DynamicAny/DynEnum_i.h"
00014 #include "tao/DynamicAny/DynAnyFactory.h"
00015 #include "tao/DynamicAny/DynAnyUtils_T.h"
00016
00017 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00018 #include "tao/CDR.h"
00019
00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00021
00022 TAO_Notify_Constraint_Visitor::TAO_Notify_Constraint_Visitor (void)
00023 : implicit_id_ (TAO_Notify_Constraint_Visitor::EMPTY),
00024 implicit_ids_(implicit_ids_size_),
00025 filterable_data_(filterable_data_size_),
00026 variable_header_(variable_header_size_)
00027 {
00028 (void) this->implicit_ids_.bind (ACE_CString ("filterable_data",
00029 0,
00030 false),
00031 FILTERABLE_DATA);
00032 (void) this->implicit_ids_.bind (ACE_CString ("header",
00033 0,
00034 false),
00035 HEADER);
00036 (void) this->implicit_ids_.bind (ACE_CString ("remainder_of_body",
00037 0,
00038 false),
00039 REMAINDER_OF_BODY);
00040 (void) this->implicit_ids_.bind (ACE_CString ("fixed_header",
00041 0,
00042 false),
00043 FIXED_HEADER);
00044 (void) this->implicit_ids_.bind (ACE_CString ("variable_header",
00045 0,
00046 false),
00047 VARIABLE_HEADER);
00048 (void) this->implicit_ids_.bind (ACE_CString ("event_name",
00049 0,
00050 false),
00051 EVENT_NAME);
00052 (void) this->implicit_ids_.bind (ACE_CString ("event_type",
00053 0,
00054 false),
00055 EVENT_TYPE);
00056 (void) this->implicit_ids_.bind (ACE_CString ("domain_name",
00057 0,
00058 false),
00059 DOMAIN_NAME);
00060 (void) this->implicit_ids_.bind (ACE_CString ("type_name",
00061 0,
00062 false),
00063 TYPE_NAME);
00064 }
00065
00066 int
00067 TAO_Notify_Constraint_Visitor::bind_structured_event (const CosNotification::StructuredEvent &s_event)
00068 {
00069
00070
00071
00072 CORBA::ULong length = s_event.filterable_data.length ();
00073 CORBA::ULong index = 0;
00074
00075 for (index = 0; index < length; ++index)
00076 {
00077 ACE_CString name_str (s_event.filterable_data[index].name, 0, false);
00078
00079 int status =
00080 this->filterable_data_.bind (
00081 name_str,
00082 s_event.filterable_data[index].value
00083 );
00084
00085 if (status != 0)
00086 return -1;
00087 }
00088
00089 length = s_event.header.variable_header.length ();
00090
00091 for (index = 0; index < length; ++index)
00092 {
00093 ACE_CString name_str (s_event.header.variable_header[index].name, 0, false);
00094
00095 int status =
00096 this->variable_header_.bind (
00097 name_str,
00098 s_event.header.variable_header[index].value
00099 );
00100
00101 if (status != 0)
00102 return -1;
00103 }
00104
00105 this->domain_name_ =
00106 CORBA::string_dup (s_event.header.fixed_header.event_type.domain_name);
00107
00108 this->type_name_ =
00109 CORBA::string_dup (s_event.header.fixed_header.event_type.type_name);
00110
00111 this->event_name_ =
00112 CORBA::string_dup (s_event.header.fixed_header.event_name);
00113
00114 this->remainder_of_body_ = s_event.remainder_of_body;
00115
00116 return 0;
00117 }
00118
00119 CORBA::Boolean
00120 TAO_Notify_Constraint_Visitor::evaluate_constraint (ETCL_Constraint* root)
00121 {
00122 CORBA::Boolean result = 0;
00123 this->queue_.reset ();
00124
00125
00126 if (root != 0)
00127 {
00128 if ((root->accept (this) == 0) && (! this->queue_.is_empty ()))
00129 {
00130 TAO_ETCL_Literal_Constraint top;
00131 this->queue_.dequeue_head (top);
00132 result = (CORBA::Boolean) top;
00133 }
00134 }
00135
00136
00137 return result;
00138 }
00139
00140 int
00141 TAO_Notify_Constraint_Visitor::visit_literal (
00142 ETCL_Literal_Constraint *literal
00143 )
00144 {
00145 TAO_ETCL_Literal_Constraint lit (literal);
00146 this->queue_.enqueue_head (lit);
00147 return 0;
00148 }
00149
00150 int
00151 TAO_Notify_Constraint_Visitor::visit_identifier (ETCL_Identifier *ident)
00152 {
00153 int return_value = -1;
00154 const char *name = ident->value ();
00155 ACE_CString key (name, 0, false);
00156
00157 CORBA::Any any;
00158
00159 if (this->filterable_data_.find (key, any) == 0)
00160 {
00161 if (any.impl () != 0)
00162 {
00163 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (&any));
00164 return_value = 0;
00165 }
00166 }
00167
00168 return return_value;
00169 }
00170
00171 int
00172 TAO_Notify_Constraint_Visitor::visit_union_value (
00173 ETCL_Union_Value *union_value
00174 )
00175 {
00176 switch (union_value->sign ())
00177 {
00178 case 0:
00179 {
00180 TAO_ETCL_Literal_Constraint lit (union_value->string ());
00181 this->queue_.enqueue_head (lit);
00182 }
00183 break;
00184 case -1:
00185 {
00186 CORBA::Long value = -(*union_value->integer ());
00187 TAO_ETCL_Literal_Constraint lit (value);
00188 this->queue_.enqueue_head (lit);
00189 }
00190 break;
00191 case 1:
00192 {
00193 TAO_ETCL_Literal_Constraint lit (union_value->integer ());
00194 this->queue_.enqueue_head (lit);
00195 }
00196 break;
00197 default:
00198 return -1;
00199 }
00200
00201 return 0;
00202 }
00203
00204 int
00205 TAO_Notify_Constraint_Visitor::visit_union_pos (
00206 ETCL_Union_Pos *union_pos
00207 )
00208 {
00209 try
00210 {
00211 if (union_pos->union_value ()->accept (this) == 0)
00212 {
00213 TAO_ETCL_Literal_Constraint disc_val;
00214 this->queue_.dequeue_head (disc_val);
00215
00216 TAO_DynUnion_i dyn_union;
00217 dyn_union.init (this->current_value_.in ());
00218
00219 CORBA::TypeCode_var tc = this->current_value_->type ();
00220
00221 switch (disc_val.expr_type ())
00222 {
00223 case ETCL_INTEGER:
00224 case ETCL_SIGNED:
00225 case ETCL_UNSIGNED:
00226 {
00227 CORBA::Any disc_any;
00228 CORBA::TypeCode_var disc_tc =
00229 tc->discriminator_type ();
00230 CORBA::TCKind disc_kind =
00231 TAO_DynAnyFactory::unalias (disc_tc.in ());
00232
00233 switch (disc_kind)
00234 {
00235 case CORBA::tk_boolean:
00236 disc_any <<= CORBA::Any::from_boolean ((CORBA::Boolean) disc_val);
00237 break;
00238 case CORBA::tk_short:
00239 disc_any <<= (CORBA::Short) ((CORBA::Long) disc_val);
00240 break;
00241 case CORBA::tk_ushort:
00242 disc_any <<= (CORBA::UShort) ((CORBA::ULong) disc_val);
00243 break;
00244 case CORBA::tk_long:
00245 disc_any <<= (CORBA::Long) disc_val;
00246 break;
00247 case CORBA::tk_ulong:
00248 disc_any <<= (CORBA::ULong) disc_val;
00249 break;
00250 case CORBA::tk_enum:
00251 {
00252 TAO_OutputCDR cdr;
00253 cdr.write_ulong ((CORBA::ULong) disc_val);
00254 TAO_InputCDR in_cdr (cdr);
00255 TAO::Unknown_IDL_Type *unk = 0;
00256 ACE_NEW_RETURN (unk,
00257 TAO::Unknown_IDL_Type (disc_tc.in (),
00258 in_cdr),
00259 -1);
00260
00261 disc_any.replace (unk);
00262 break;
00263 }
00264
00265
00266
00267
00268 case CORBA::tk_longlong:
00269 case CORBA::tk_ulonglong:
00270 case CORBA::tk_char:
00271 case CORBA::tk_wchar:
00272 default:
00273 return -1;
00274 }
00275
00276 DynamicAny::DynAny_var dyn_any =
00277 TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any &> (
00278 disc_tc.in (),
00279 disc_any);
00280 dyn_union.set_discriminator (dyn_any.in ());
00281 DynamicAny::DynAny_var u_member =
00282 dyn_union.member ();
00283 this->current_value_ =
00284 u_member->to_any ();
00285
00286 break;
00287 }
00288 case ETCL_STRING:
00289 {
00290 const char *name = (const char *) disc_val;
00291 CORBA::ULong count = tc->member_count ();
00292
00293 const char *member_name = 0;
00294 CORBA::ULong i = 0;
00295
00296 for (i = 0; i < count; ++i)
00297 {
00298 member_name = tc->member_name (i);
00299
00300 if (ACE_OS::strcmp (name, member_name) == 0)
00301 {
00302 break;
00303 }
00304 }
00305
00306
00307
00308
00309 this->current_value_ = tc->member_label (i);
00310
00311 break;
00312 }
00313
00314
00315 default:
00316 return -1;
00317 }
00318
00319 ETCL_Constraint *nested = union_pos->component ();
00320
00321
00322
00323
00324
00325 if (nested == 0)
00326 {
00327 TAO_ETCL_Literal_Constraint lit (this->current_value_.ptr ());
00328 this->queue_.enqueue_head (lit);
00329 return 0;
00330 }
00331 else
00332 {
00333 return nested->accept (this);
00334 }
00335 }
00336 else
00337 {
00338 return -1;
00339 }
00340 }
00341 catch (const CORBA::Exception&)
00342 {
00343 return -1;
00344 }
00345 }
00346
00347 int
00348 TAO_Notify_Constraint_Visitor::visit_component_pos (
00349 ETCL_Component_Pos *pos
00350 )
00351 {
00352 try
00353 {
00354
00355
00356 CORBA::TypeCode_var tc = this->current_value_->type ();
00357 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00358
00359 DynamicAny::DynAny_var member;
00360 CORBA::Boolean success = 0;
00361 CORBA::ULong slot = (CORBA::ULong) *pos->integer ();
00362
00363 switch (kind)
00364 {
00365 case CORBA::tk_enum:
00366 {
00367 TAO_DynEnum_i dyn_enum;
00368 dyn_enum.init (this->current_value_.in ());
00369 success = dyn_enum.seek (slot);
00370
00371 if (!success)
00372 {
00373 return -1;
00374 }
00375
00376 member = dyn_enum.current_component ();
00377 break;
00378 }
00379 case CORBA::tk_struct:
00380 {
00381 TAO_DynStruct_i dyn_struct;
00382 dyn_struct.init (this->current_value_.in ());
00383 success = dyn_struct.seek (slot);
00384
00385 if (!success)
00386 {
00387 return -1;
00388 }
00389
00390 member = dyn_struct.current_component ();
00391 break;
00392 }
00393
00394
00395
00396
00397 default:
00398 return -1;
00399 }
00400
00401 CORBA::Any_var value = member->to_any ();
00402 ETCL_Constraint *comp = pos->component ();
00403
00404 if (comp == 0)
00405 {
00406 TAO_ETCL_Literal_Constraint result (value.ptr ());
00407 this->queue_.enqueue_head (result);
00408 return 0;
00409 }
00410 else
00411 {
00412 this->current_value_ = value._retn ();
00413 return comp->accept (this);
00414 }
00415 }
00416 catch (const CORBA::Exception&)
00417 {
00418 return -1;
00419 }
00420 }
00421
00422 int
00423 TAO_Notify_Constraint_Visitor::visit_component_assoc (
00424 ETCL_Component_Assoc *assoc
00425 )
00426 {
00427 CORBA::Any any;
00428 ACE_CString name (assoc->identifier ()->value (),
00429 0,
00430 false);
00431
00432 switch (this->implicit_id_)
00433 {
00434 case FILTERABLE_DATA:
00435 if (this->filterable_data_.find (name, any) != 0 || any.impl () == 0)
00436 {
00437 return -1;
00438 }
00439 break;
00440 case VARIABLE_HEADER:
00441 if (this->variable_header_.find (name, any) != 0|| any.impl () == 0)
00442 {
00443 return -1;
00444 }
00445 break;
00446
00447
00448 default:
00449 return -1;
00450 }
00451
00452 ETCL_Constraint *comp = assoc->component ();
00453 CORBA::Any *any_ptr = 0;
00454
00455 if (comp == 0)
00456 {
00457 TAO_ETCL_Literal_Constraint result (&any);
00458 this->queue_.enqueue_head (result);
00459
00460
00461
00462 ACE_NEW_RETURN (any_ptr,
00463 CORBA::Any,
00464 -1);
00465
00466 (*any_ptr) <<= name.c_str ();
00467 this->current_value_ = any_ptr;
00468
00469 return 0;
00470 }
00471 else
00472 {
00473 ACE_NEW_RETURN (any_ptr,
00474 CORBA::Any (any),
00475 -1);
00476
00477 this->current_value_ = any_ptr;
00478 return comp->accept (this);
00479 }
00480 }
00481
00482 int
00483 TAO_Notify_Constraint_Visitor::visit_component_array (
00484 ETCL_Component_Array *array
00485 )
00486 {
00487 try
00488 {
00489
00490
00491
00492 CORBA::TypeCode_var tc = this->current_value_->type ();
00493 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00494
00495 DynamicAny::DynAny_var member;
00496 CORBA::Boolean success = 0;
00497 CORBA::ULong slot = (CORBA::ULong) *array->integer ();
00498
00499 switch (kind)
00500 {
00501 case CORBA::tk_array:
00502 {
00503 TAO_DynEnum_i dyn_array;
00504 dyn_array.init (this->current_value_.in ());
00505 success = dyn_array.seek (slot);
00506
00507 if (!success)
00508 {
00509 return -1;
00510 }
00511
00512 member = dyn_array.current_component ();
00513 break;
00514 }
00515 case CORBA::tk_sequence:
00516 {
00517 TAO_DynStruct_i dyn_sequence;
00518 dyn_sequence.init (this->current_value_.in ());
00519 success = dyn_sequence.seek (slot);
00520
00521 if (!success)
00522 {
00523 return -1;
00524 }
00525
00526 member =dyn_sequence.current_component ();
00527 break;
00528 }
00529
00530
00531 default:
00532 return -1;
00533 }
00534
00535 CORBA::Any_var value = member->to_any ();
00536 ETCL_Constraint *comp = array->component ();
00537
00538 if (comp == 0)
00539 {
00540 TAO_ETCL_Literal_Constraint result (value.ptr ());
00541 this->queue_.enqueue_head (result);
00542 return 0;
00543 }
00544 else
00545 {
00546 this->current_value_ = value._retn ();
00547 return comp->accept (this);
00548 }
00549 }
00550 catch (const CORBA::Exception&)
00551 {
00552 return -1;
00553 }
00554 }
00555
00556 int
00557 TAO_Notify_Constraint_Visitor::visit_special (ETCL_Special *special)
00558 {
00559 try
00560 {
00561 CORBA::TypeCode_var tc = this->current_value_->type ();
00562 tc = TAO_DynAnyFactory::strip_alias (tc.in ());
00563 CORBA::TCKind kind = tc->kind ();
00564
00565 switch (special->type ())
00566 {
00567 case ETCL_LENGTH:
00568 {
00569 CORBA::ULong length;
00570
00571 switch (kind)
00572 {
00573 case CORBA::tk_sequence:
00574 {
00575 TAO_DynSequence_i dyn_seq;
00576 dyn_seq.init (current_value_.in());
00577
00578 DynamicAny::AnySeq_var any_seq =
00579 dyn_seq.get_elements ();
00580
00581 length = any_seq->length ();
00582 }
00583 break;
00584 case CORBA::tk_array:
00585 length = tc->length ();
00586 break;
00587 default:
00588 return -1;
00589 }
00590
00591 TAO_ETCL_Literal_Constraint lit (length);
00592 this->queue_.enqueue_head (lit);
00593 return 0;
00594 }
00595 case ETCL_DISCRIMINANT:
00596 {
00597
00598
00599 TAO_DynUnion_i dyn_union;
00600 dyn_union.init (this->current_value_.in ());
00601
00602 DynamicAny::DynAny_var disc =
00603 dyn_union.get_discriminator ();
00604
00605 CORBA::Any_var disc_any = disc->to_any ();
00606
00607 TAO_ETCL_Literal_Constraint lit (disc_any.ptr ());
00608 this->queue_.enqueue_head (lit);
00609 return 0;
00610 }
00611 case ETCL_TYPE_ID:
00612 {
00613 const char *name = tc->name ();
00614
00615 TAO_ETCL_Literal_Constraint lit (name);
00616 this->queue_.enqueue_head (lit);
00617 return 0;
00618 }
00619 case ETCL_REPOS_ID:
00620 {
00621 const char *id = tc->id ();
00622
00623 TAO_ETCL_Literal_Constraint lit (id);
00624 this->queue_.enqueue_head (lit);
00625 return 0;
00626 }
00627 default:
00628 return -1;
00629 }
00630 }
00631 catch (const CORBA::Exception&)
00632 {
00633 return -1;
00634 }
00635 }
00636
00637 int
00638 TAO_Notify_Constraint_Visitor::visit_component (
00639 ETCL_Component *component
00640 )
00641 {
00642 ETCL_Constraint *nested = component->component ();
00643 ETCL_Identifier *identifier = component->identifier ();
00644 ACE_CString component_name (identifier->value (),
00645 0,
00646 false);
00647 CORBA::Any *any_ptr = 0;
00648 int result =
00649 this->implicit_ids_.find (component_name, this->implicit_id_);
00650
00651 if (result != 0)
00652 {
00653 this->implicit_id_ = TAO_Notify_Constraint_Visitor::EMPTY;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 if (this->implicit_id_ == TAO_Notify_Constraint_Visitor::EMPTY)
00665 {
00666 ACE_NEW_RETURN (any_ptr,
00667 CORBA::Any,
00668 -1);
00669
00670 if (nested == 0)
00671 {
00672
00673
00674 (*any_ptr) <<= component_name.c_str ();
00675 this->current_value_ = any_ptr;
00676 return identifier->accept (this);
00677 }
00678 else
00679 {
00680 int result = identifier->accept (this);
00681
00682 if (result != 0)
00683 {
00684 return result;
00685 }
00686
00687 TAO_ETCL_Literal_Constraint id;
00688 this->queue_.dequeue_head (id);
00689
00690 any_ptr->replace (id);
00691 any_ptr->impl ()->_add_ref ();
00692 this->current_value_ = any_ptr;
00693 }
00694 }
00695
00696 if (nested != 0)
00697 {
00698 return nested->accept (this);
00699 }
00700 else
00701 {
00702 switch (this->implicit_id_)
00703 {
00704 case TYPE_NAME:
00705 {
00706 TAO_ETCL_Literal_Constraint tn (this->type_name_.in ());
00707 this->queue_.enqueue_head (tn);
00708 return 0;
00709 }
00710 case EVENT_NAME:
00711 {
00712 TAO_ETCL_Literal_Constraint en (this->event_name_.in ());
00713 this->queue_.enqueue_head (en);
00714 return 0;
00715 }
00716 case DOMAIN_NAME:
00717 {
00718 TAO_ETCL_Literal_Constraint dn (this->domain_name_.in ());
00719 this->queue_.enqueue_head (dn);
00720 return 0;
00721 }
00722 case REMAINDER_OF_BODY:
00723 {
00724 TAO_ETCL_Literal_Constraint rob (&this->remainder_of_body_);
00725 this->queue_.enqueue_head (rob);
00726 return 0;
00727 }
00728
00729
00730
00731 default:
00732 return -1;
00733 }
00734 }
00735 }
00736
00737 int
00738 TAO_Notify_Constraint_Visitor::visit_dot (ETCL_Dot *dot)
00739 {
00740
00741
00742
00743 return dot->component ()->accept (this);
00744 }
00745
00746 int
00747 TAO_Notify_Constraint_Visitor::visit_eval (ETCL_Eval *eval)
00748 {
00749
00750 return eval->component ()->accept (this);
00751 }
00752
00753 int
00754 TAO_Notify_Constraint_Visitor::visit_default (ETCL_Default *def)
00755 {
00756 ETCL_Constraint *comp = def->component ();
00757
00758 if (comp == 0)
00759 {
00760 return -1;
00761 }
00762
00763 if (comp->accept (this) != 0)
00764 {
00765 return -1;
00766 }
00767
00768 try
00769 {
00770 CORBA::TypeCode_var tc = this->current_value_->type ();
00771
00772
00773
00774 CORBA::Long default_index = tc->default_index ();
00775
00776
00777 if (default_index == -1)
00778 {
00779 TAO_ETCL_Literal_Constraint result (false);
00780 this->queue_.enqueue_head (result);
00781 return 0;
00782 }
00783
00784
00785 TAO_ETCL_Literal_Constraint disc_value;
00786 this->queue_.dequeue_head (disc_value);
00787 TAO_ETCL_Literal_Constraint default_index_value (default_index);
00788
00789 return (disc_value == default_index_value);
00790 }
00791 catch (const CORBA::Exception&)
00792 {
00793 return -1;
00794 }
00795 }
00796
00797 int
00798 TAO_Notify_Constraint_Visitor::visit_exist (ETCL_Exist *exist)
00799 {
00800 ETCL_Constraint *component = exist->component ();
00801
00802 if (component->accept (this) == 0)
00803 {
00804 const char *value = 0;
00805 CORBA::Boolean result = 0;
00806
00807
00808
00809
00810
00811 if (this->implicit_id_ == FILTERABLE_DATA
00812 || this->implicit_id_ == VARIABLE_HEADER)
00813 {
00814 this->current_value_ >>= value;
00815 }
00816 else if (this->implicit_id_ == EMPTY)
00817 {
00818
00819
00820
00821 ETCL_Identifier* ident =
00822 dynamic_cast<ETCL_Identifier*> (component);
00823
00824 if (ident != 0)
00825 {
00826 this->implicit_id_ = FILTERABLE_DATA;
00827 value = ident->value ();
00828 }
00829 }
00830
00831 switch (this->implicit_id_)
00832 {
00833 case FILTERABLE_DATA:
00834 result =
00835 (this->filterable_data_.find (ACE_CString (value, 0, false)) == 0);
00836 break;
00837 case VARIABLE_HEADER:
00838 result =
00839 (this->variable_header_.find (ACE_CString (value, 0, false)) == 0);
00840 break;
00841 case TYPE_NAME:
00842 result = (this->type_name_.in () != 0);
00843 break;
00844 case EVENT_NAME:
00845 result = (this->event_name_.in () != 0);
00846 break;
00847 case DOMAIN_NAME:
00848 result = (this->domain_name_.in () != 0);
00849 break;
00850
00851 default:
00852 return -1;
00853 }
00854
00855 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
00856
00857 return 0;
00858 }
00859
00860 return -1;
00861 }
00862
00863 int
00864 TAO_Notify_Constraint_Visitor::visit_unary_expr (
00865 ETCL_Unary_Expr *unary_expr
00866 )
00867 {
00868 ETCL_Constraint *subexpr = unary_expr->subexpr ();
00869
00870 if (subexpr->accept (this) == 0)
00871 {
00872 TAO_ETCL_Literal_Constraint subexpr_result;
00873 CORBA::Boolean result = false;
00874 int op_type = unary_expr->type ();
00875
00876 switch (op_type)
00877 {
00878 case ETCL_NOT:
00879 this->queue_.dequeue_head (subexpr_result);
00880 result = ! (CORBA::Boolean) subexpr_result;
00881 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
00882 return 0;
00883 case ETCL_MINUS:
00884
00885
00886
00887 this->queue_.dequeue_head (subexpr_result);
00888 this->queue_.enqueue_head (-subexpr_result);
00889 return 0;
00890 case ETCL_PLUS:
00891
00892
00893 return 0;
00894 default:
00895
00896
00897 return -1;
00898 }
00899 }
00900
00901 return -1;
00902 }
00903
00904 int
00905 TAO_Notify_Constraint_Visitor::visit_binary_expr (
00906 ETCL_Binary_Expr *binary_expr
00907 )
00908 {
00909 int bin_op_type = binary_expr->type ();
00910
00911 switch (bin_op_type)
00912 {
00913 case ETCL_OR:
00914 return this->visit_or (binary_expr);
00915 case ETCL_AND:
00916 return this->visit_and (binary_expr);
00917 case ETCL_LT:
00918 case ETCL_LE:
00919 case ETCL_GT:
00920 case ETCL_GE:
00921 case ETCL_EQ:
00922 case ETCL_NE:
00923 case ETCL_PLUS:
00924 case ETCL_MINUS:
00925 case ETCL_MULT:
00926 case ETCL_DIV:
00927 return this->visit_binary_op (binary_expr, bin_op_type);
00928 case ETCL_TWIDDLE:
00929 return this->visit_twiddle (binary_expr);
00930 case ETCL_IN:
00931 return this->visit_in (binary_expr);
00932 default:
00933 return -1;
00934 }
00935 }
00936
00937 int
00938 TAO_Notify_Constraint_Visitor::visit_or (
00939 ETCL_Binary_Expr *binary
00940 )
00941 {
00942 int return_value = -1;
00943 CORBA::Boolean result = false;
00944 ETCL_Constraint *lhs = binary->lhs ();
00945
00946 if (lhs->accept (this) == 0)
00947 {
00948 TAO_ETCL_Literal_Constraint lhs_result;
00949 this->queue_.dequeue_head (lhs_result);
00950 result = (CORBA::Boolean) lhs_result;
00951
00952
00953 if (result == 0)
00954 {
00955 ETCL_Constraint *rhs = binary->rhs ();
00956
00957 if (rhs->accept (this) == 0)
00958 {
00959 TAO_ETCL_Literal_Constraint rhs_result;
00960 this->queue_.dequeue_head (rhs_result);
00961 result = (CORBA::Boolean) rhs_result;
00962 return_value = 0;
00963 }
00964 }
00965 else
00966 {
00967 return_value = 0;
00968 }
00969 }
00970
00971 if (return_value == 0)
00972 {
00973 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
00974 }
00975
00976 return return_value;
00977 }
00978
00979 int
00980 TAO_Notify_Constraint_Visitor::visit_and (ETCL_Binary_Expr *binary)
00981 {
00982 int return_value = -1;
00983 CORBA::Boolean result = false;
00984 ETCL_Constraint *lhs = binary->lhs ();
00985
00986 if (lhs->accept (this) == 0)
00987 {
00988 TAO_ETCL_Literal_Constraint lhs_result;
00989 this->queue_.dequeue_head (lhs_result);
00990 result = (CORBA::Boolean) lhs_result;
00991
00992
00993 if (result == true)
00994 {
00995 ETCL_Constraint *rhs = binary->rhs ();
00996
00997 if (rhs->accept (this) == 0)
00998 {
00999 TAO_ETCL_Literal_Constraint rhs_result;
01000 this->queue_.dequeue_head (rhs_result);
01001 result = (CORBA::Boolean) rhs_result;
01002 return_value = 0;
01003 }
01004 }
01005 else
01006 {
01007 return_value = 0;
01008 }
01009 }
01010
01011 if (return_value == 0)
01012 {
01013 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01014 }
01015
01016 return return_value;
01017 }
01018
01019 int
01020 TAO_Notify_Constraint_Visitor::visit_binary_op (ETCL_Binary_Expr *binary,
01021 int op_type)
01022 {
01023 int return_value = -1;
01024 ETCL_Constraint *lhs = binary->lhs ();
01025 CORBA::Boolean result = false;
01026
01027
01028
01029 if (lhs->accept (this) == 0)
01030 {
01031 TAO_ETCL_Literal_Constraint left_operand;
01032 this->queue_.dequeue_head (left_operand);
01033 ETCL_Constraint *rhs = binary->rhs ();
01034
01035 if (rhs->accept (this) == 0)
01036 {
01037 TAO_ETCL_Literal_Constraint right_operand;
01038 this->queue_.dequeue_head (right_operand);
01039 return_value = 0;
01040
01041 switch (op_type)
01042 {
01043 case ETCL_LT:
01044 result = left_operand < right_operand;
01045 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01046 break;
01047 case ETCL_LE:
01048
01049 result = left_operand.operator<= (right_operand);
01050 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01051 break;
01052 case ETCL_GT:
01053
01054 result = left_operand.operator> (right_operand);
01055 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01056 break;
01057 case ETCL_GE:
01058
01059 result = left_operand.operator>= (right_operand);
01060 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01061 break;
01062 case ETCL_EQ:
01063 result = left_operand == right_operand;
01064 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01065 break;
01066 case ETCL_NE:
01067
01068 result = left_operand.operator!= (right_operand);
01069 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01070 break;
01071 case ETCL_PLUS:
01072 this->queue_.enqueue_head (left_operand + right_operand);
01073 break;
01074 case ETCL_MINUS:
01075 this->queue_.enqueue_head (left_operand - right_operand);
01076 break;
01077 case ETCL_MULT:
01078 this->queue_.enqueue_head (left_operand * right_operand);
01079 break;
01080 case ETCL_DIV:
01081 this->queue_.enqueue_head (left_operand / right_operand);
01082 break;
01083 default:
01084 return_value = -1;
01085 }
01086 }
01087 }
01088
01089 return return_value;
01090 }
01091
01092 int
01093 TAO_Notify_Constraint_Visitor::visit_twiddle (ETCL_Binary_Expr *binary)
01094 {
01095 int return_value = -1;
01096 ETCL_Constraint *lhs = binary->lhs ();
01097
01098
01099 if (lhs->accept (this) == 0)
01100 {
01101 TAO_ETCL_Literal_Constraint left;
01102 this->queue_.dequeue_head (left);
01103 ETCL_Constraint *rhs = binary->rhs ();
01104
01105 if (rhs->accept (this) == 0)
01106 {
01107 TAO_ETCL_Literal_Constraint right;
01108 this->queue_.dequeue_head (right);
01109 CORBA::Boolean result =
01110 (ACE_OS::strstr ((const char *) right,
01111 (const char *) left) != 0);
01112 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01113 return_value = 0;
01114 }
01115 }
01116
01117 return return_value;
01118 }
01119
01120 int
01121 TAO_Notify_Constraint_Visitor::visit_in (ETCL_Binary_Expr *binary)
01122 {
01123 int return_value = -1;
01124 ETCL_Constraint *lhs = binary->lhs ();
01125
01126
01127 if (lhs->accept (this) == 0)
01128 {
01129 TAO_ETCL_Literal_Constraint left;
01130 this->queue_.dequeue_head (left);
01131
01132 ETCL_Constraint *rhs = binary->rhs ();
01133
01134 if (rhs->accept (this) == 0)
01135 {
01136 TAO_ETCL_Literal_Constraint bag;
01137 this->queue_.dequeue_head (bag);
01138
01139 if (bag.expr_type () == ETCL_COMPONENT)
01140 {
01141 CORBA::Any_ptr any_ptr = 0;
01142 ACE_NEW_RETURN (any_ptr,
01143 CORBA::Any,
01144 -1);
01145
01146 CORBA::Any_var component = any_ptr;
01147 component->replace (bag);
01148 component->impl ()->_add_ref ();
01149 CORBA::TCKind kind = CORBA::tk_null;
01150
01151 try
01152 {
01153 CORBA::TypeCode_var tc = component->type ();
01154 kind = TAO_DynAnyFactory::unalias (tc.in ());
01155 }
01156 catch (const CORBA::Exception&)
01157 {
01158 return return_value;
01159 }
01160
01161 CORBA::Boolean result = 0;
01162
01163 switch (kind)
01164 {
01165 case CORBA::tk_sequence:
01166 result = this->sequence_does_contain (&component.in (),
01167 left);
01168 break;
01169 case CORBA::tk_array:
01170 result = this->array_does_contain (&component.in (),
01171 left);
01172 break;
01173 case CORBA::tk_struct:
01174 result = this->struct_does_contain (&component.in (),
01175 left);
01176 break;
01177 case CORBA::tk_union:
01178 result = this->union_does_contain (&component.in (),
01179 left);
01180 break;
01181 case CORBA::tk_any:
01182 result = this->any_does_contain (&component.in (),
01183 left);
01184 break;
01185 default:
01186 return return_value;
01187 }
01188
01189 this->queue_.enqueue_head (TAO_ETCL_Literal_Constraint (result));
01190 return_value = 0;
01191 }
01192 }
01193 }
01194
01195 return return_value;
01196 }
01197
01198 int
01199 TAO_Notify_Constraint_Visitor::visit_preference (ETCL_Preference *)
01200 {
01201
01202
01203
01204
01205 return -1;
01206 }
01207
01208 CORBA::Boolean
01209 TAO_Notify_Constraint_Visitor::sequence_does_contain (
01210 const CORBA::Any *any,
01211 TAO_ETCL_Literal_Constraint &item
01212 )
01213 {
01214 try
01215 {
01216 CORBA::TypeCode_var type = any->type ();
01217 CORBA::TypeCode_var base_type =
01218 TAO_DynAnyFactory::strip_alias (type.in ());
01219 CORBA::TypeCode_var content_type =
01220 base_type->content_type ();
01221 CORBA::TCKind kind =
01222 TAO_DynAnyFactory::unalias (content_type.in ());
01223
01224
01225
01226 CORBA::Boolean match =
01227 this->simple_type_match (item.expr_type (),
01228 kind);
01229
01230 if (!match)
01231 {
01232 return false;
01233 }
01234
01235 TAO_DynSequence_i dyn_seq;
01236 dyn_seq.init (*any);
01237
01238 DynamicAny::AnySeq_var any_seq = dyn_seq.get_elements ();
01239
01240 CORBA::ULong length = any_seq->length ();
01241
01242 for (CORBA::ULong i = 0; i < length; ++i)
01243 {
01244 TAO_ETCL_Literal_Constraint element (&any_seq[i]);
01245
01246 if (item == element)
01247 {
01248 return true;
01249 }
01250 }
01251 }
01252 catch (const CORBA::Exception&)
01253 {
01254 return false;
01255 }
01256
01257 return false;
01258 }
01259
01260 CORBA::Boolean
01261 TAO_Notify_Constraint_Visitor::array_does_contain (
01262 const CORBA::Any *any,
01263 TAO_ETCL_Literal_Constraint &item
01264 )
01265 {
01266 try
01267 {
01268 CORBA::TypeCode_var type = any->type ();
01269 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (type.in ());
01270
01271
01272
01273 CORBA::Boolean match =
01274 this->simple_type_match (item.expr_type (),
01275 kind);
01276
01277 if (!match)
01278 {
01279 return false;
01280 }
01281
01282 TAO_DynArray_i dyn_array;
01283 dyn_array.init (*any);
01284
01285 DynamicAny::AnySeq_var any_seq = dyn_array.get_elements ();
01286
01287 CORBA::ULong length = any_seq->length ();
01288
01289 for (CORBA::ULong i = 0; i < length; ++i)
01290 {
01291 TAO_ETCL_Literal_Constraint element (&any_seq[i]);
01292
01293 if (item == element)
01294 {
01295 return true;
01296 }
01297 }
01298 }
01299 catch (const CORBA::Exception&)
01300 {
01301 return false;
01302 }
01303
01304 return false;
01305 }
01306
01307 CORBA::Boolean
01308 TAO_Notify_Constraint_Visitor::struct_does_contain (
01309 const CORBA::Any *any,
01310 TAO_ETCL_Literal_Constraint &item
01311 )
01312 {
01313 try
01314 {
01315 TAO_DynStruct_i dyn_struct;
01316 dyn_struct.init (*any);
01317
01318 DynamicAny::NameValuePairSeq_var members =
01319 dyn_struct.get_members ();
01320
01321 CORBA::ULong length = members->length ();
01322 CORBA::TypeCode_var tc;
01323 CORBA::TCKind kind;
01324
01325 for (CORBA::ULong i = 0; i < length; ++i)
01326 {
01327 tc = members[i].value.type ();
01328 kind = TAO_DynAnyFactory::unalias (tc.in ());
01329
01330
01331
01332 CORBA::Boolean match =
01333 this->simple_type_match (item.expr_type (),
01334 kind);
01335
01336 if (!match)
01337 {
01338 continue;
01339 }
01340
01341 TAO_ETCL_Literal_Constraint element (&members[i].value);
01342
01343 if (item == element)
01344 {
01345 return true;
01346 }
01347 }
01348 }
01349 catch (const CORBA::Exception&)
01350 {
01351 return false;
01352 }
01353
01354 return false;
01355 }
01356
01357 CORBA::Boolean
01358 TAO_Notify_Constraint_Visitor::union_does_contain (
01359 const CORBA::Any *any,
01360 TAO_ETCL_Literal_Constraint &item
01361 )
01362 {
01363 try
01364 {
01365 TAO_DynUnion_i dyn_union;
01366 dyn_union.init (*any);
01367
01368 DynamicAny::DynAny_var cc =
01369 dyn_union.current_component ();
01370
01371 CORBA::Any_var member = cc->to_any ();
01372
01373 CORBA::TypeCode_var tc = member->type ();
01374 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
01375
01376
01377
01378 CORBA::Boolean match =
01379 this->simple_type_match (item.expr_type (),
01380 kind);
01381
01382 if (!match)
01383 {
01384 return false;
01385 }
01386
01387 TAO_ETCL_Literal_Constraint element (&member.inout ());
01388
01389 return (item == element);
01390 }
01391 catch (const CORBA::Exception&)
01392 {
01393 return false;
01394 }
01395 }
01396
01397 CORBA::Boolean
01398 TAO_Notify_Constraint_Visitor::any_does_contain (
01399 const CORBA::Any *any,
01400 TAO_ETCL_Literal_Constraint &item
01401 )
01402 {
01403 const CORBA::Any *result = 0;
01404 *any >>= result;
01405
01406 TAO_ETCL_Literal_Constraint element (const_cast<CORBA::Any *>(result));
01407 return item == element;
01408 }
01409
01410 CORBA::Boolean
01411 TAO_Notify_Constraint_Visitor::simple_type_match (int expr_type,
01412 CORBA::TCKind tc_kind)
01413 {
01414 switch (expr_type)
01415 {
01416 case ETCL_STRING:
01417 if (tc_kind != CORBA::tk_string)
01418 {
01419 return false;
01420 }
01421 break;
01422 case ETCL_DOUBLE:
01423 if (tc_kind != CORBA::tk_double && tc_kind != CORBA::tk_float)
01424 {
01425 return false;
01426 }
01427 break;
01428 case ETCL_INTEGER:
01429 case ETCL_SIGNED:
01430 if (tc_kind != CORBA::tk_short
01431 && tc_kind != CORBA::tk_long
01432 && tc_kind != CORBA::tk_longlong)
01433 {
01434 return false;
01435 }
01436 break;
01437 case ETCL_UNSIGNED:
01438 if (tc_kind != CORBA::tk_ushort
01439 && tc_kind != CORBA::tk_ulong
01440 && tc_kind != CORBA::tk_ulonglong)
01441 {
01442 return false;
01443 }
01444 break;
01445 case ETCL_BOOLEAN:
01446 if (tc_kind != CORBA::tk_boolean)
01447 {
01448 return false;
01449 }
01450 break;
01451 default:
01452 return false;
01453 }
01454
01455 return true;
01456 }
01457
01458 const size_t TAO_Notify_Constraint_Visitor::implicit_ids_size_ = 27;
01459 const size_t TAO_Notify_Constraint_Visitor::filterable_data_size_ = 31;
01460 const size_t TAO_Notify_Constraint_Visitor::variable_header_size_ = 31;
01461
01462 TAO_END_VERSIONED_NAMESPACE_DECL