00001
00002
00003 #include "orbsvcs/Notify/ETCL_Filter.h"
00004
00005 ACE_RCSID(Notify,
00006 TAO_Notify_ETCL_Filter,
00007 "$Id: ETCL_Filter.cpp 85541 2009-06-06 06:24:05Z johnnyw $")
00008
00009 #include "ace/Auto_Ptr.h"
00010 #include "tao/debug.h"
00011 #include "orbsvcs/Notify/Notify_Constraint_Visitors.h"
00012 #include "orbsvcs/Notify/Topology_Saver.h"
00013
00014 #ifndef DEBUG_LEVEL
00015 # define DEBUG_LEVEL TAO_debug_level
00016 #endif //DEBUG_LEVEL
00017
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 TAO_Notify_Constraint_Expr::TAO_Notify_Constraint_Expr (void)
00021 {
00022 }
00023
00024
00025 TAO_Notify_Constraint_Expr::~TAO_Notify_Constraint_Expr ()
00026 {
00027 }
00028
00029
00030 void
00031 TAO_Notify_Constraint_Expr::save_persistent (
00032 TAO_Notify::Topology_Saver& saver)
00033 {
00034 CosNotification::EventTypeSeq& event_types = this->constr_expr.event_types;
00035 CORBA::ULong len = event_types.length ();
00036 for (CORBA::ULong i = 0; i < len; ++i)
00037 {
00038 TAO_Notify::NVPList attrs;
00039 bool changed = true;
00040
00041 attrs.push_back(TAO_Notify::NVP("Domain", event_types[i].domain_name.in()));
00042 attrs.push_back(TAO_Notify::NVP("Type", event_types[i].type_name.in()));
00043 saver.begin_object(0, "EventType", attrs, changed);
00044 saver.end_object(0, "EventType");
00045 }
00046 }
00047
00048
00049 void
00050 TAO_Notify_Constraint_Expr::load_attrs(
00051 const TAO_Notify::NVPList& attrs)
00052 {
00053 TAO_Notify_Object::load_attrs (attrs);
00054 const char* expr = 0;
00055 if (attrs.find ("Expression", expr))
00056 {
00057 this->constr_expr.constraint_expr = CORBA::string_dup (expr);
00058 }
00059 }
00060
00061
00062 TAO_Notify::Topology_Object*
00063 TAO_Notify_Constraint_Expr::load_child (
00064 const ACE_CString &type,
00065 CORBA::Long id,
00066 const TAO_Notify::NVPList& attrs)
00067 {
00068 ACE_UNUSED_ARG (id);
00069 TAO_Notify::Topology_Object* result = this;
00070 if (type == "EventType")
00071 {
00072 const char* domain = 0;
00073 const char* type = 0;
00074 attrs.find ("Domain", domain);
00075 attrs.find ("Type", type);
00076
00077 CORBA::ULong len = this->constr_expr.event_types.length ();
00078 if (DEBUG_LEVEL)
00079 ACE_DEBUG ((LM_DEBUG,
00080 ACE_TEXT ("(%P|%t) reload EventType %d \n"),
00081 len + 1));
00082
00083 this->constr_expr.event_types.length (len + 1);
00084 this->constr_expr.event_types[len].domain_name = CORBA::string_dup (domain);
00085 this->constr_expr.event_types[len].type_name = CORBA::string_dup (type);
00086
00087 this->interpreter.build_tree (this->constr_expr);
00088 }
00089
00090 return result;
00091 }
00092
00093
00094 void
00095 TAO_Notify_Constraint_Expr::release (void)
00096 {
00097 delete this;
00098
00099 }
00100
00101
00102
00103 TAO_Notify_ETCL_Filter::TAO_Notify_ETCL_Filter (PortableServer::POA_ptr poa,
00104 const char *constraint_grammar,
00105 const TAO_Notify_Object::ID& id)
00106 :constraint_expr_ids_ (0),
00107 poa_ (PortableServer::POA::_duplicate (poa)),
00108 id_ (id),
00109 grammar_ (constraint_grammar)
00110 {
00111 }
00112
00113
00114 TAO_Notify_ETCL_Filter::~TAO_Notify_ETCL_Filter ()
00115 {
00116 try
00117 {
00118 this->destroy();
00119 }
00120 catch (const CORBA::Exception&)
00121 {
00122 if (TAO_debug_level)
00123 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Error in Filter dtor\n")));
00124
00125
00126 }
00127
00128 if (TAO_debug_level > 1)
00129 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Filter Destroyed\n")));
00130 }
00131
00132 char*
00133 TAO_Notify_ETCL_Filter::constraint_grammar (void)
00134 {
00135 return CORBA::string_dup (this->grammar_.c_str ());
00136 }
00137
00138 void
00139 TAO_Notify_ETCL_Filter::add_constraints_i (
00140 const CosNotifyFilter::ConstraintInfoSeq& constraint_info_seq)
00141 {
00142 for (CORBA::ULong index = 0; index < constraint_info_seq.length (); ++index)
00143 {
00144 this->add_constraint_i (constraint_info_seq[index]);
00145 }
00146 }
00147
00148 TAO_Notify_Constraint_Expr*
00149 TAO_Notify_ETCL_Filter::add_constraint_i (CosNotifyFilter::ConstraintID cnstr_id)
00150 {
00151 TAO_Notify_Constraint_Expr* notify_constr_expr = 0;
00152
00153 ACE_NEW_THROW_EX (notify_constr_expr,
00154 TAO_Notify_Constraint_Expr (),
00155 CORBA::NO_MEMORY ());
00156 auto_ptr <TAO_Notify_Constraint_Expr> auto_expr (notify_constr_expr);
00157
00158 if (TAO_debug_level > 1)
00159 ACE_DEBUG ((LM_DEBUG,
00160 ACE_TEXT("Added an empty constraint to filter\n")));
00161
00162 if (this->constraint_expr_list_.bind (cnstr_id, notify_constr_expr) == -1)
00163 throw CORBA::INTERNAL ();
00164
00165 auto_expr.release ();
00166
00167 return notify_constr_expr;
00168 }
00169
00170
00171 void
00172 TAO_Notify_ETCL_Filter::add_constraint_i
00173 (const CosNotifyFilter::ConstraintInfo& constraint,
00174 CosNotifyFilter::ConstraintID cnstr_id)
00175 {
00176 TAO_Notify_Constraint_Expr* notify_constr_expr = 0;
00177
00178 ACE_NEW_THROW_EX (notify_constr_expr,
00179 TAO_Notify_Constraint_Expr (),
00180 CORBA::NO_MEMORY ());
00181 auto_ptr <TAO_Notify_Constraint_Expr> auto_expr (notify_constr_expr);
00182
00183 CosNotifyFilter::ConstraintExp const & expr =
00184 constraint.constraint_expression;
00185
00186 notify_constr_expr->interpreter.build_tree (expr);
00187
00188 notify_constr_expr->constr_expr = expr;
00189
00190 if (cnstr_id == 0)
00191 {
00192 if (TAO_debug_level > 1)
00193 ACE_DEBUG ((LM_DEBUG,
00194 ACE_TEXT ("Added constraint %C to filter %d\n"),
00195 expr.constraint_expr.in (), this->id_));
00196
00197 cnstr_id = ++constraint_expr_ids_;
00198 }
00199 else
00200 {
00201 if (TAO_debug_level > 1)
00202 ACE_DEBUG ((LM_DEBUG,
00203 ACE_TEXT ("Loaded constraint %C to filter %d\n"),
00204 expr.constraint_expr.in (), this->id_));
00205 }
00206
00207 if (this->constraint_expr_list_.bind (cnstr_id, notify_constr_expr) == -1)
00208 throw CORBA::INTERNAL ();
00209
00210 auto_expr.release ();
00211 }
00212
00213
00214 CosNotifyFilter::ConstraintInfoSeq*
00215 TAO_Notify_ETCL_Filter::add_constraints (
00216 const CosNotifyFilter::ConstraintExpSeq& constraint_list)
00217 {
00218 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00219 CORBA::INTERNAL ());
00220
00221 CORBA::ULong const constraint_length = constraint_list.length ();
00222
00223 if (TAO_debug_level > 0)
00224 ACE_DEBUG ((LM_DEBUG,
00225 ACE_TEXT ("constraint_length = %d\n"),
00226 constraint_length));
00227
00228
00229 CosNotifyFilter::ConstraintInfoSeq* infoseq_ptr;
00230 ACE_NEW_THROW_EX (infoseq_ptr,
00231 CosNotifyFilter::ConstraintInfoSeq (constraint_length),
00232 CORBA::NO_MEMORY ());
00233
00234 CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00235 infoseq->length (constraint_length);
00236
00237
00238 for (CORBA::ULong pop_index = 0; pop_index < constraint_length; ++pop_index)
00239 {
00240 infoseq[pop_index].constraint_expression =
00241 constraint_list [pop_index];
00242
00243 if (TAO_debug_level > 0)
00244 {
00245 ACE_DEBUG ((LM_DEBUG,
00246 ACE_TEXT ("Adding constraint %d, %C\n"),
00247 pop_index,
00248 constraint_list [pop_index].constraint_expr.in ()));
00249 }
00250 }
00251
00252 this->add_constraints_i (infoseq.in ());
00253
00254 return infoseq._retn ();
00255 }
00256
00257 void
00258 TAO_Notify_ETCL_Filter::modify_constraints (
00259 const CosNotifyFilter::ConstraintIDSeq & del_list,
00260 const CosNotifyFilter::ConstraintInfoSeq & modify_list)
00261 {
00262 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00263 CORBA::INTERNAL ());
00264
00265
00266 CORBA::ULong index;
00267
00268 for (index = 0; index < del_list.length (); ++index)
00269 {
00270 if (this->constraint_expr_list_.find (del_list [index]) == -1)
00271 {
00272 throw CosNotifyFilter::ConstraintNotFound (del_list [index]);
00273 }
00274 }
00275
00276 for (index = 0; index < modify_list.length (); ++index)
00277 {
00278 if (this->constraint_expr_list_.find (modify_list [index].constraint_id) == -1)
00279 {
00280 throw CosNotifyFilter::ConstraintNotFound (
00281 modify_list [index].constraint_id);
00282 }
00283 }
00284
00285
00286 ACE_Array<TAO_Notify_Constraint_Expr*> constr_saved (modify_list.length ());
00287 TAO_Notify_Constraint_Expr* constr_expr = 0;
00288
00289 for (index = 0; index < modify_list.length (); ++index)
00290 {
00291 CosNotifyFilter::ConstraintID cnstr_id =
00292 modify_list [index].constraint_id;
00293
00294 if (this->constraint_expr_list_.unbind (cnstr_id, constr_expr) != -1)
00295 {
00296 constr_saved[index] = constr_expr;
00297 }
00298 }
00299
00300
00301
00302 try
00303 {
00304 this->add_constraints_i (modify_list);
00305 }
00306 catch (const CORBA::Exception&)
00307 {
00308
00309 for (index = 0; index < modify_list.length (); ++index)
00310 {
00311 CosNotifyFilter::ConstraintID cnstr_id = ++this->constraint_expr_ids_;
00312
00313 if (constraint_expr_list_.bind (cnstr_id, constr_saved[index]) == -1)
00314 throw CORBA::NO_RESOURCES ();
00315 }
00316
00317 throw;
00318 }
00319
00320
00321
00322 for (index = 0; index < del_list.length (); ++index)
00323 {
00324 if (this->constraint_expr_list_.unbind (del_list [index], constr_expr) != -1)
00325 {
00326 delete constr_expr;
00327 }
00328 }
00329
00330
00331 for (index = 0; index < constr_saved.max_size (); ++index)
00332 {
00333 delete constr_saved[index];
00334 }
00335
00336 this->self_change ();
00337 }
00338
00339 CosNotifyFilter::ConstraintInfoSeq*
00340 TAO_Notify_ETCL_Filter::get_constraints (
00341 const CosNotifyFilter::ConstraintIDSeq & id_list)
00342 {
00343 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00344 CORBA::INTERNAL ());
00345
00346
00347 CosNotifyFilter::ConstraintInfoSeq *infoseq_ptr;
00348 ACE_NEW_THROW_EX (infoseq_ptr,
00349 CosNotifyFilter::ConstraintInfoSeq (id_list.length ()),
00350 CORBA::NO_MEMORY ());
00351
00352 CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00353
00354 TAO_Notify_Constraint_Expr *notify_constr_expr = 0;
00355
00356 for (CORBA::ULong index = 0; index < id_list.length (); ++index)
00357 {
00358 if (this->constraint_expr_list_.find (id_list[index],
00359 notify_constr_expr) == -1)
00360 throw CosNotifyFilter::ConstraintNotFound (id_list[index]);
00361
00362 infoseq[index].constraint_expression =
00363 notify_constr_expr->constr_expr;
00364
00365
00366 infoseq[index].constraint_id = id_list[index];
00367 }
00368
00369 return infoseq._retn ();
00370 }
00371
00372 CosNotifyFilter::ConstraintInfoSeq *
00373 TAO_Notify_ETCL_Filter::get_all_constraints (void)
00374 {
00375 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00376 CORBA::INTERNAL ());
00377
00378 CORBA::ULong const current_size =
00379 static_cast<CORBA::ULong> (this->constraint_expr_list_.current_size ());
00380
00381
00382 CosNotifyFilter::ConstraintInfoSeq *infoseq_ptr;
00383 ACE_NEW_THROW_EX (infoseq_ptr,
00384 CosNotifyFilter::ConstraintInfoSeq (current_size),
00385 CORBA::NO_MEMORY ());
00386
00387 CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00388
00389 infoseq->length (current_size);
00390
00391 CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00392 CONSTRAINT_EXPR_LIST::ENTRY *entry;
00393
00394 for (u_int index = 0; iter.done () == 0; iter.advance (), ++index)
00395 {
00396 if (iter.next (entry) != 0)
00397 {
00398
00399
00400
00401
00402 infoseq[index].constraint_expression =
00403 static_cast<const CosNotifyFilter::ConstraintExp> (entry->int_id_->constr_expr);
00404
00405 infoseq[index].constraint_id = entry->ext_id_;
00406 }
00407 }
00408
00409 return infoseq._retn ();
00410 }
00411
00412 void
00413 TAO_Notify_ETCL_Filter::remove_all_constraints (void)
00414 {
00415 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00416 CORBA::INTERNAL ());
00417
00418 this->remove_all_constraints_i ();
00419 }
00420
00421 void
00422 TAO_Notify_ETCL_Filter::remove_all_constraints_i (void)
00423 {
00424 CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00425 CONSTRAINT_EXPR_LIST::ENTRY *entry;
00426
00427 for (CORBA::ULong index = 0; iter.done () == 0; iter.advance (), ++index)
00428 {
00429 if (iter.next (entry) != 0)
00430 {
00431 delete entry->int_id_;
00432 entry->int_id_ = 0;
00433 }
00434 }
00435
00436 this->constraint_expr_list_.unbind_all ();
00437 }
00438
00439 void
00440 TAO_Notify_ETCL_Filter::destroy (void)
00441 {
00442 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00443 CORBA::INTERNAL ());
00444
00445 if (!CORBA::is_nil (this->poa_.in()))
00446 {
00447 this->remove_all_constraints_i ();
00448
00449 PortableServer::ObjectId_var refTemp = this->poa_->servant_to_id (this);
00450 this->poa_->deactivate_object (refTemp.in ());
00451 this->poa_ = PortableServer::POA::_nil();
00452 }
00453 }
00454
00455 CORBA::Boolean
00456 TAO_Notify_ETCL_Filter::match (const CORBA::Any & )
00457 {
00458 throw CORBA::NO_IMPLEMENT ();
00459 }
00460
00461 CORBA::Boolean
00462 TAO_Notify_ETCL_Filter::match_structured (
00463 const CosNotification::StructuredEvent & filterable_data)
00464 {
00465 ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00466 CORBA::INTERNAL ());
00467
00468
00469 CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00470 CONSTRAINT_EXPR_LIST::ENTRY *entry;
00471
00472 TAO_Notify_Constraint_Visitor visitor;
00473
00474 if (visitor.bind_structured_event (filterable_data) != 0)
00475 {
00476
00477 return 0;
00478 }
00479
00480 for (; iter.done () == 0; iter.advance ())
00481 {
00482 if (iter.next (entry) != 0)
00483 {
00484 if (entry->int_id_->interpreter.evaluate (visitor) == 1)
00485 {
00486 return 1;
00487 }
00488 }
00489 }
00490
00491 return 0;
00492 }
00493
00494 CORBA::Boolean
00495 TAO_Notify_ETCL_Filter::match_typed (
00496 const CosNotification::PropertySeq & )
00497 {
00498 throw CORBA::NO_IMPLEMENT ();
00499 }
00500
00501 CosNotifyFilter::CallbackID
00502 TAO_Notify_ETCL_Filter::attach_callback (
00503 CosNotifyComm::NotifySubscribe_ptr )
00504 {
00505 throw CORBA::NO_IMPLEMENT ();
00506 }
00507
00508 void
00509 TAO_Notify_ETCL_Filter::detach_callback (
00510 CosNotifyFilter::CallbackID )
00511 {
00512 throw CORBA::NO_IMPLEMENT ();
00513 }
00514
00515 CosNotifyFilter::CallbackIDSeq *
00516 TAO_Notify_ETCL_Filter::get_callbacks (void)
00517 {
00518 throw CORBA::NO_IMPLEMENT ();
00519 }
00520
00521
00522 void
00523 TAO_Notify_ETCL_Filter::save_persistent (TAO_Notify::Topology_Saver& saver)
00524 {
00525 TAO_Notify::NVPList attrs;
00526 bool changed = true;
00527 attrs.push_back(TAO_Notify::NVP("FilterId", this->id_));
00528 attrs.push_back(TAO_Notify::NVP("Grammar", this->constraint_grammar()));
00529 saver.begin_object(0, "filter", attrs, changed);
00530
00531 {
00532 int index = 0;
00533 CONSTRAINT_EXPR_LIST::ITERATOR iterator (this->constraint_expr_list_);
00534
00535 for (CONSTRAINT_EXPR_LIST::ENTRY *entry = 0;
00536 iterator.next (entry) != 0;
00537 iterator.advance (), ++index)
00538 {
00539 TAO_Notify::NVPList attrs;
00540 bool changed = true;
00541 attrs.push_back(TAO_Notify::NVP("ConstraintId", entry->ext_id_));
00542 attrs.push_back(TAO_Notify::NVP("Expression",
00543 entry->int_id_->constr_expr.constraint_expr.in ()));
00544 saver.begin_object(0, "constraint", attrs, changed);
00545
00546 entry->int_id_->save_persistent (saver);
00547
00548 saver.end_object(0, "constraint");
00549 }
00550
00551 saver.end_object(0, "filter");
00552 }
00553 }
00554
00555
00556 void
00557 TAO_Notify_ETCL_Filter::release (void)
00558 {
00559 delete this;
00560
00561 }
00562
00563
00564 void
00565 TAO_Notify_ETCL_Filter::load_attrs(const TAO_Notify::NVPList& attrs)
00566 {
00567 const char* value = 0;
00568 TAO_Notify_Object::load_attrs (attrs);
00569 if (attrs.find ("FilterId", value))
00570 {
00571 ACE_ASSERT (this->id_ == ACE_OS::atoi (value));
00572 }
00573
00574 if (attrs.find ("Grammar", value))
00575 {
00576 this->grammar_ = value;
00577 }
00578 }
00579
00580 TAO_Notify::Topology_Object*
00581 TAO_Notify_ETCL_Filter::load_child (const ACE_CString &type,
00582 CORBA::Long, const TAO_Notify::NVPList& attrs)
00583 {
00584 TAO_Notify::Topology_Object* result = this;
00585 if (type == "constraint")
00586 {
00587 const char* value = 0;
00588 if (attrs.find ("ConstraintId", value))
00589 {
00590 TAO_Notify_Object::ID id = ACE_OS::atoi (value);
00591 constraint_expr_ids_ = id;
00592
00593 if (DEBUG_LEVEL)
00594 ACE_DEBUG ((LM_DEBUG,
00595 ACE_TEXT ("(%P|%t) reload filter %d constraint %d\n"),
00596 static_cast<int> (this->id_), static_cast<int> (id)));
00597
00598 TAO_Notify_Constraint_Expr* expr
00599 = this->add_constraint_i (id);
00600 expr->load_attrs (attrs);
00601
00602 return expr;
00603 }
00604 }
00605 return result;
00606 }
00607
00608
00609 TAO_END_VERSIONED_NAMESPACE_DECL