ETCL_Filter.cpp

Go to the documentation of this file.
00001 // $Id: ETCL_Filter.cpp 80974 2008-03-17 13:40:44Z johnnyw $
00002 
00003 #include "orbsvcs/Notify/ETCL_Filter.h"
00004 
00005 ACE_RCSID(Notify,
00006           TAO_Notify_ETCL_Filter,
00007           "$Id: ETCL_Filter.cpp 80974 2008-03-17 13:40:44Z johnnyw $")
00008 
00009 #include "ace/Auto_Ptr.h"
00010 #include "tao/debug.h"
00011 #include "orbsvcs/Notify/Notify_Constraint_Visitors.h"
00012 
00013 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 TAO_Notify_ETCL_Filter::TAO_Notify_ETCL_Filter (PortableServer::POA_ptr poa)
00016   : constraint_expr_ids_ (0),
00017     poa_ (PortableServer::POA::_duplicate (poa))
00018 {
00019 }
00020 
00021 TAO_Notify_ETCL_Filter::~TAO_Notify_ETCL_Filter ()
00022 {
00023   try
00024     {
00025       this->remove_all_constraints ();
00026     }
00027   catch (const CORBA::Exception&)
00028     {
00029       if (TAO_debug_level)
00030         ACE_DEBUG ((LM_DEBUG, "Error in Filter dtor\n"));
00031 
00032       // @@ eat exception.
00033     }
00034 
00035   if (TAO_debug_level > 1)
00036       ACE_DEBUG ((LM_DEBUG, "Filter Destroyed\n"));
00037 }
00038 
00039 char*
00040 TAO_Notify_ETCL_Filter::constraint_grammar (void)
00041 {
00042   return CORBA::string_dup ("ETCL");
00043 }
00044 
00045 void
00046 TAO_Notify_ETCL_Filter::add_constraints_i (
00047   const CosNotifyFilter::ConstraintInfoSeq& constraint_info_seq)
00048 {
00049   for (CORBA::ULong index = 0; index < constraint_info_seq.length (); ++index)
00050     {
00051       TAO_Notify_Constraint_Expr* notify_constr_expr = 0;
00052 
00053       ACE_NEW_THROW_EX (notify_constr_expr,
00054                         TAO_Notify_Constraint_Expr (),
00055                         CORBA::NO_MEMORY ());
00056       auto_ptr <TAO_Notify_Constraint_Expr> auto_expr (notify_constr_expr);
00057 
00058       const CosNotifyFilter::ConstraintExp& expr =
00059         constraint_info_seq[index].constraint_expression;
00060 
00061       notify_constr_expr->interpreter.
00062         build_tree (expr.constraint_expr.in ());
00063 
00064       notify_constr_expr->constr_expr = expr;
00065 
00066       CosNotifyFilter::ConstraintID cnstr_id = ++constraint_expr_ids_;
00067 
00068       if (this->constraint_expr_list_.bind (cnstr_id, notify_constr_expr) == -1)
00069         throw CORBA::INTERNAL ();
00070 
00071       if (TAO_debug_level > 1)
00072         ACE_DEBUG ((LM_DEBUG, "Added constraint to filter %x\n", this, expr.constraint_expr.in ()));
00073 
00074       auto_expr.release ();
00075     }
00076 }
00077 
00078 CosNotifyFilter::ConstraintInfoSeq*
00079 TAO_Notify_ETCL_Filter::add_constraints (
00080   const CosNotifyFilter::ConstraintExpSeq& constraint_list)
00081 {
00082   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00083                       CORBA::INTERNAL ());
00084 
00085   CORBA::ULong constraint_length = constraint_list.length ();
00086 
00087   if (TAO_debug_level > 0)
00088       ACE_DEBUG ((LM_DEBUG, "constraint_length = %d\n",
00089                   constraint_length));
00090 
00091   // Create the list that goes out.
00092   CosNotifyFilter::ConstraintInfoSeq* infoseq_ptr;
00093   ACE_NEW_THROW_EX (infoseq_ptr,
00094                     CosNotifyFilter::ConstraintInfoSeq (constraint_length),
00095                     CORBA::NO_MEMORY ());
00096 
00097   CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00098   infoseq->length (constraint_length);
00099 
00100   // Populate infoseq.
00101   for (CORBA::ULong pop_index = 0; pop_index < constraint_length; ++pop_index)
00102     {
00103       infoseq[pop_index].constraint_expression =
00104         constraint_list [pop_index];
00105 
00106       if (TAO_debug_level > 0)
00107         {
00108           ACE_DEBUG ((LM_DEBUG,
00109                       "Adding constraint %d, %s\n",
00110                       pop_index,
00111                       constraint_list [pop_index].constraint_expr.in ()));
00112         }
00113     }
00114 
00115   this->add_constraints_i (infoseq.in ());
00116 
00117   return infoseq._retn ();
00118 }
00119 
00120 void
00121 TAO_Notify_ETCL_Filter::modify_constraints (
00122   const CosNotifyFilter::ConstraintIDSeq & del_list,
00123   const CosNotifyFilter::ConstraintInfoSeq & modify_list)
00124 {
00125   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00126                       CORBA::INTERNAL ());
00127 
00128   // First check if all the ids are valid.
00129   u_int index;
00130 
00131   for (index = 0; index < del_list.length (); ++index)
00132     {
00133       if (this->constraint_expr_list_.find (del_list [index]) == -1)
00134         {
00135           throw CosNotifyFilter::ConstraintNotFound (del_list [index]);
00136         }
00137     }
00138 
00139   for (index = 0; index < modify_list.length (); ++index)
00140     {
00141       if (this->constraint_expr_list_.find (modify_list [index].constraint_id) == -1)
00142         {
00143           throw CosNotifyFilter::ConstraintNotFound (
00144             modify_list [index].constraint_id);
00145         }
00146     }
00147 
00148   // Remove previous entries and save them in case we need to reinstate them.
00149   ACE_Array<TAO_Notify_Constraint_Expr*> constr_saved (modify_list.length ());
00150   TAO_Notify_Constraint_Expr* constr_expr = 0;
00151 
00152   for (index = 0; index < modify_list.length (); ++index)
00153     {
00154       CosNotifyFilter::ConstraintID cnstr_id =
00155         modify_list [index].constraint_id;
00156 
00157       if (this->constraint_expr_list_.unbind (cnstr_id, constr_expr) != -1)
00158         {
00159           constr_saved[index] = constr_expr;
00160         }
00161     }
00162 
00163   // Now add the new entries.
00164   // Keep a list of ids generated in this session.
00165   try
00166     {
00167       this->add_constraints_i (modify_list);
00168     }
00169   catch (const CORBA::Exception&)
00170     {
00171       // Restore,
00172       for (index = 0; index < modify_list.length (); ++index)
00173         {
00174           CosNotifyFilter::ConstraintID cnstr_id = ++this->constraint_expr_ids_;
00175 
00176           if (constraint_expr_list_.bind (cnstr_id, constr_saved[index]) == -1)
00177             throw CORBA::NO_RESOURCES ();
00178         }
00179 
00180       throw;
00181     }
00182 
00183   // Now go around deleting...
00184   // for the del_list.
00185   for (index = 0; index < del_list.length (); ++index)
00186     {
00187       if (this->constraint_expr_list_.unbind (del_list [index], constr_expr) != -1)
00188         {
00189           delete constr_expr;
00190         }
00191     }
00192 
00193   // Delete the old constraints.
00194   for (index = 0; index < constr_saved.max_size (); ++index)
00195     {
00196       delete constr_saved[index];
00197     }
00198 }
00199 
00200 CosNotifyFilter::ConstraintInfoSeq*
00201 TAO_Notify_ETCL_Filter::get_constraints (
00202   const CosNotifyFilter::ConstraintIDSeq & id_list)
00203 {
00204   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00205                       CORBA::INTERNAL ());
00206 
00207   // Create the list that goes out.
00208   CosNotifyFilter::ConstraintInfoSeq *infoseq_ptr;
00209   ACE_NEW_THROW_EX (infoseq_ptr,
00210                     CosNotifyFilter::ConstraintInfoSeq (id_list.length ()),
00211                     CORBA::NO_MEMORY ());
00212 
00213   CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00214 
00215   TAO_Notify_Constraint_Expr *notify_constr_expr = 0;
00216 
00217   for (u_int index = 0; index < id_list.length (); ++index)
00218     {
00219       if (this->constraint_expr_list_.find (id_list[index],
00220                                             notify_constr_expr) == -1)
00221         throw CosNotifyFilter::ConstraintNotFound (id_list[index]);
00222 
00223       infoseq[index].constraint_expression =
00224         notify_constr_expr->constr_expr;
00225 
00226       // Get an id.
00227       infoseq[index].constraint_id = id_list[index];
00228     }
00229 
00230   return infoseq._retn ();
00231 }
00232 
00233 CosNotifyFilter::ConstraintInfoSeq *
00234 TAO_Notify_ETCL_Filter::get_all_constraints (void)
00235 {
00236   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00237                       CORBA::INTERNAL ());
00238 
00239   CORBA::ULong current_size = static_cast<CORBA::ULong> (this->constraint_expr_list_.current_size ());
00240 
00241   // Create the list that goes out.
00242   CosNotifyFilter::ConstraintInfoSeq *infoseq_ptr;
00243   ACE_NEW_THROW_EX (infoseq_ptr,
00244                     CosNotifyFilter::ConstraintInfoSeq (current_size),
00245                     CORBA::NO_MEMORY ());
00246 
00247   CosNotifyFilter::ConstraintInfoSeq_var infoseq (infoseq_ptr);
00248 
00249   infoseq->length (current_size);
00250 
00251   CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00252   CONSTRAINT_EXPR_LIST::ENTRY *entry;
00253 
00254   for (u_int index = 0; iter.done () == 0; iter.advance (), ++index)
00255     {
00256       if (iter.next (entry) != 0)
00257         {
00258           // Why do we cast to a const object?
00259           // We want to force the TAO::String_Manager to make a
00260           // copy of the string. It wouldn't unless we coax it to use
00261           // the correct assignment operator.
00262           infoseq[index].constraint_expression =
00263             static_cast<const CosNotifyFilter::ConstraintExp> (entry->int_id_->constr_expr);
00264 
00265           infoseq[index].constraint_id = entry->ext_id_;
00266         }
00267     }
00268 
00269   return infoseq._retn ();
00270 }
00271 
00272 void
00273 TAO_Notify_ETCL_Filter::remove_all_constraints (void)
00274 {
00275   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00276                       CORBA::INTERNAL ());
00277 
00278   this->remove_all_constraints_i ();
00279 }
00280 
00281 void
00282 TAO_Notify_ETCL_Filter::remove_all_constraints_i (void)
00283 {
00284   CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00285   CONSTRAINT_EXPR_LIST::ENTRY *entry;
00286 
00287   u_int index;
00288 
00289   for (index = 0; iter.done () == 0; iter.advance (), ++index)
00290     {
00291       if (iter.next (entry) != 0)
00292         {
00293           delete entry->int_id_;
00294           entry->int_id_ = 0;
00295         }
00296     }
00297 
00298   this->constraint_expr_list_.unbind_all ();
00299 }
00300 
00301 void
00302 TAO_Notify_ETCL_Filter::destroy (void)
00303 {
00304   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00305                       CORBA::INTERNAL ());
00306 
00307   this->remove_all_constraints_i ();
00308 
00309   PortableServer::ObjectId_var refTemp = poa_->servant_to_id (this);
00310 
00311   poa_->deactivate_object (refTemp.in ());
00312 }
00313 
00314 CORBA::Boolean
00315 TAO_Notify_ETCL_Filter::match (const CORBA::Any & /*filterable_data */)
00316 {
00317   throw CORBA::NO_IMPLEMENT ();
00318 }
00319 
00320 CORBA::Boolean
00321 TAO_Notify_ETCL_Filter::match_structured (
00322   const CosNotification::StructuredEvent & filterable_data)
00323 {
00324   ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_,
00325                       CORBA::INTERNAL ());
00326 
00327   // We want to return true if at least one constraint matches.
00328   CONSTRAINT_EXPR_LIST::ITERATOR iter (this->constraint_expr_list_);
00329   CONSTRAINT_EXPR_LIST::ENTRY *entry;
00330 
00331   TAO_Notify_Constraint_Visitor visitor;
00332 
00333   if (visitor.bind_structured_event (filterable_data) != 0)
00334     {
00335       // Maybe throw some kind of exception here, or lower down,
00336       return 0;
00337     }
00338 
00339   for (; iter.done () == 0; iter.advance ())
00340     {
00341       if (iter.next (entry) != 0)
00342         {
00343           if (entry->int_id_->interpreter.evaluate (visitor) == 1)
00344             {
00345               return 1;
00346             }
00347         }
00348     }
00349 
00350   return 0;
00351 }
00352 
00353 CORBA::Boolean
00354 TAO_Notify_ETCL_Filter::match_typed (
00355                             const CosNotification::PropertySeq & /* filterable_data */
00356                             )
00357 {
00358   throw CORBA::NO_IMPLEMENT ();
00359 }
00360 
00361 CosNotifyFilter::CallbackID
00362 TAO_Notify_ETCL_Filter::attach_callback (
00363   CosNotifyComm::NotifySubscribe_ptr /* callback */)
00364 {
00365   throw CORBA::NO_IMPLEMENT ();
00366 }
00367 
00368 void
00369 TAO_Notify_ETCL_Filter::detach_callback (
00370   CosNotifyFilter::CallbackID /* callback */)
00371 {
00372   throw CORBA::NO_IMPLEMENT ();
00373 }
00374 
00375 CosNotifyFilter::CallbackIDSeq *
00376 TAO_Notify_ETCL_Filter::get_callbacks (void)
00377 {
00378   throw CORBA::NO_IMPLEMENT ();
00379 }
00380 
00381 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:45:29 2010 for TAO_CosNotification by  doxygen 1.4.7