ETCL_Filter.cpp

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

Generated on Sun Jan 27 15:39:54 2008 for TAO_CosNotification by doxygen 1.3.6