EventChannelFactory.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; -*-
00002 //                            Package   : omniEvents
00003 // EventChannelFactory_i.cc   Created   : 1/4/98
00004 //                            Author    : Paul Nader (pwn)
00005 //
00006 //    Copyright (C) 1998 Paul Nader.
00007 //
00008 //    This file is part of the omniEvents application.
00009 //
00010 //    omniEvents is free software; you can redistribute it and/or
00011 //    modify it under the terms of the GNU Lesser General Public
00012 //    License as published by the Free Software Foundation; either
00013 //    version 2.1 of the License, or (at your option) any later version.
00014 //
00015 //    omniEvents is distributed in the hope that it will be useful,
00016 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //    Lesser General Public License for more details.
00019 //
00020 //    You should have received a copy of the GNU Lesser General Public
00021 //    License along with this library; if not, write to the Free Software
00022 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // Description:
00025 //      Implementation of the COSS Event Services Event Channel Factory
00026 //      
00027 
00028 #include "EventChannelFactory.h"
00029 
00030 #include "Orb.h"
00031 #include "EventChannel.h"
00032 #include "PersistNode.h"
00033 
00034 #include <memory>
00035 
00036 #ifdef HAVE_OMNIORB4
00037 #  define STR_MATCH(s1,s2) omni::strMatch((s1),(s2))
00038 #else
00039 #  define STR_MATCH(s1,s2) (0==::strcmp((s1),(s2)))
00040 #endif
00041 
00042 namespace OmniEvents {
00043 
00044 //------------------------------------------------------------------------
00045 //           Event Channel Factory Interface Implementation
00046 //------------------------------------------------------------------------
00047 EventChannelFactory_i::EventChannelFactory_i(const PersistNode& node)
00048 : Servant(Orb::inst()._omniINSPOA.in()),
00049   _port(node.attrLong("port",11169)),
00050   _endPointNoListen(node.attrString("endPointNoListen")),
00051   _channels()
00052 {
00053   // Create event channels
00054   for(map<string,PersistNode*>::const_iterator i=node._child.begin();
00055       i!=node._child.end();
00056       ++i)
00057   {
00058     EventChannel_i* channel =new EventChannel_i(&_channels);
00059     channel->activate(
00060       i->first.c_str(), // channelName
00061       i->second         // node
00062     );
00063     channel->start();
00064   }
00065   activateObjectWithId("omniEvents");
00066 }
00067 
00068 
00069 CORBA::Boolean
00070 EventChannelFactory_i::supports(const CosLifeCycle::Key &k)
00071 {
00072   if((k.length() == 1) &&
00073      (strcmp(k[0].id, "EventChannel") == 0) &&
00074      (strcmp(k[0].kind, "object interface") == 0))
00075     return 1;
00076   else
00077     return 0;
00078 }
00079 
00080 
00081 CORBA::Object_ptr
00082 EventChannelFactory_i::create_object(
00083   const CosLifeCycle::Key& k,
00084   const CosLifeCycle::Criteria& criteria
00085 )
00086 {
00087   // Check the key
00088   if(!this->supports(k))
00089       throw CosLifeCycle::NoFactory(k);
00090 
00091   // Process criteria !! MAY THROW !!
00092   auto_ptr<PersistNode> criteriaNode( parseCriteria(criteria) );
00093 
00094   CORBA::String_var channelId;
00095   if(criteriaNode->hasAttr("InsName"))
00096       channelId=criteriaNode->attrString("InsName").c_str();
00097   else
00098       channelId=newUniqueId();
00099 
00100   // Create the channel.
00101   // We place it into an auto_ptr - this will automatically clean up if anything
00102   // goes wrong.
00103   auto_ptr<EventChannel_i> channel( new EventChannel_i(&_channels) );
00104   try
00105   {
00106     channel->activate(channelId.in(),criteriaNode.get()); // !! MAY THROW !!
00107   }
00108   catch(PortableServer::POA::ObjectAlreadyActive& ex)
00109   {
00110     throw CosLifeCycle::InvalidCriteria(criteria); //??
00111   }
00112   catch(PortableServer::POA::AdapterAlreadyExists& ex) // create_POA
00113   {
00114     throw CosLifeCycle::InvalidCriteria(criteria); //??
00115   }
00116 
00117   // Start the channel's thread running. We release() the pointer, as the
00118   // thread will delete it when it stops.
00119   channel->start();
00120   return channel.release()->_this();
00121 }
00122 
00123 
00124 CosEventChannelAdmin::EventChannel_ptr
00125 EventChannelFactory_i::create_channel(const char* channel_name)
00126 {
00127   CosEventChannelAdmin::EventChannel_var result;
00128 
00129   CosLifeCycle::Key key;
00130   key.length(1);
00131   key[0].id  ="EventChannel";
00132   key[0].kind="object interface";
00133 
00134   CosLifeCycle::Criteria criteria;
00135   criteria.length(1);
00136   criteria[0].name    = "InsName";
00137   criteria[0].value <<= channel_name;
00138 
00139   try
00140   {
00141     CORBA::Object_var obj=create_object(key,criteria);
00142     result=CosEventChannelAdmin::EventChannel::_narrow(obj.in());
00143   }
00144   catch(CosLifeCycle::InvalidCriteria& ex)
00145   {
00146     if(ex.invalid_criteria.length()>0 &&
00147        STR_MATCH(ex.invalid_criteria[0].name,"InsName"))
00148     {
00149       throw event::NameAlreadyUsed();
00150     }
00151     else
00152     {
00153       DB(10,"Failed to create_channel."
00154         " Converting InvalidCriteria exception into UNKNOWN.")
00155       throw CORBA::UNKNOWN();
00156     }
00157   }
00158   catch(CORBA::UserException& ex)
00159   {
00160     DB(2,"Failed to create_channel. Converting UserException"
00161       IFELSE_OMNIORB4(" '"<<ex._name()<<"'",<<) " into UNKNOWN.")
00162     throw CORBA::UNKNOWN();
00163   }
00164   return result._retn();
00165 }
00166 
00167 
00168 CosEventChannelAdmin::EventChannel_ptr
00169 EventChannelFactory_i::join_channel(const char* channel_name)
00170 {
00171   using namespace PortableServer;
00172   CosEventChannelAdmin::EventChannel_var result;
00173   try
00174   {
00175     ObjectId_var oid =PortableServer::string_to_ObjectId(channel_name);
00176     CORBA::Object_var obj =Orb::inst()._omniINSPOA->id_to_reference(oid.in());
00177     result=CosEventChannelAdmin::EventChannel::_narrow(obj.in());
00178   }
00179   catch(POA::ObjectNotActive&)
00180   {
00181     DB(10,"Failed to join_channel. Object not active.")
00182     throw event::EventChannelNotFound();
00183   }
00184   catch(CORBA::UserException& ex)
00185   {
00186     DB(2,"Failed to join_channel. Converting UserException"
00187       IFELSE_OMNIORB4(" '"<<ex._name()<<"'",<<) " into UNKNOWN.")
00188     throw CORBA::UNKNOWN();
00189   }
00190   return result._retn();
00191 }
00192 
00193 
00194 PersistNode* EventChannelFactory_i::parseCriteria(
00195   const CosLifeCycle::Criteria &criteria
00196 ) const
00197 {
00198   using namespace CosLifeCycle;
00199   auto_ptr<PersistNode> result( new PersistNode() );
00200 
00201   for(CORBA::ULong i=0; i<criteria.length(); i++)
00202   {
00203     if(strcmp(criteria[i].name, "PullRetryPeriod_ms") == 0)
00204     {
00205       CORBA::ULong pullRetryPeriod_ms;
00206       if(! (criteria[i].value >>= pullRetryPeriod_ms))
00207           throw InvalidCriteria(extract("PullRetryPeriod_ms",criteria));
00208       if(pullRetryPeriod_ms <= 0)
00209           throw CannotMeetCriteria(extract("PullRetryPeriod_ms",criteria));
00210       result->addattr("PullRetryPeriod_ms",pullRetryPeriod_ms);
00211     }
00212     else if(strcmp(criteria[i].name, "PullRetryPeriod") == 0)
00213     {
00214       // This criterion has been deprecated in favour of PullRetryPeriod_ms.
00215       // Don't overwrite any value provided by the latter.
00216       if(!result->hasAttr("PullRetryPeriod_ms"))
00217       {
00218         CORBA::ULong pullRetryPeriod;
00219         if(! (criteria[i].value >>= pullRetryPeriod))
00220             throw InvalidCriteria(extract("PullRetryPeriod",criteria));
00221         if(pullRetryPeriod <= 0)
00222             throw CannotMeetCriteria(extract("PullRetryPeriod",criteria));
00223         result->addattr("PullRetryPeriod_ms",pullRetryPeriod*1000);
00224       }
00225     }
00226     else if(strcmp(criteria[i].name, "MaxQueueLength") == 0)
00227     {
00228       CORBA::ULong maxQueueLength;
00229       if(! (criteria[i].value >>= maxQueueLength))
00230           throw InvalidCriteria(extract("MaxQueueLength",criteria));
00231       if(maxQueueLength > 0)
00232           result->addattr("MaxQueueLength",maxQueueLength);
00233       else
00234           DB(10,"Ignoring CosLifeCycle criterion: MaxQueueLength=0");
00235     }
00236     else if(strcmp(criteria[i].name, "MaxNumProxies") == 0)
00237     {
00238       CORBA::ULong maxNumProxies;
00239       if(! (criteria[i].value >>= maxNumProxies))
00240           throw InvalidCriteria(extract("MaxNumProxies",criteria));
00241       if(maxNumProxies > 0)
00242           result->addattr("MaxNumProxies",maxNumProxies);
00243       else
00244           DB(10,"Ignoring CosLifeCycle criterion: MaxNumProxies=0");
00245     }
00246     else if(strcmp(criteria[i].name, "CyclePeriod_ns") == 0)
00247     {
00248       CORBA::ULong cyclePeriod_ns;
00249       if(! (criteria[i].value >>= cyclePeriod_ns))
00250           throw InvalidCriteria(extract("CyclePeriod_ns",criteria));
00251       if(cyclePeriod_ns > 0)
00252           result->addattr("CyclePeriod_ns",cyclePeriod_ns);
00253       else
00254           DB(10,"Ignoring CosLifeCycle criterion: CyclePeriod_ns=0");
00255     }
00256     else if(strcmp(criteria[i].name, "InsName") == 0)
00257     {
00258       const char* insName;
00259       if(! (criteria[i].value >>= insName))
00260           throw InvalidCriteria(extract("InsName",criteria));
00261       if(insName && insName[0])
00262           result->addattr(string("InsName=")+insName);
00263       else
00264           DB(10,"Ignoring empty CosLifeCycle criterion: InsName");
00265     }
00266     else if(strcmp(criteria[i].name, "FilterId") == 0)
00267     {
00268       const char* repositoryId;
00269       if(! (criteria[i].value >>= repositoryId))
00270           throw InvalidCriteria(extract("FilterId",criteria));
00271       if(repositoryId && repositoryId[0])
00272           result->addattr(string("FilterId=")+repositoryId);
00273       else
00274           DB(10,"Ignoring empty CosLifeCycle criterion: FilterId");
00275     }
00276     else if(strcmp(criteria[i].name, "MaxEventsPerConsumer") == 0)
00277     {
00278       DB(10,"Ignoring obsolete CosLifeCycle criterion: MaxEventsPerConsumer");
00279     }
00280     else
00281     {
00282       DB(10,"Ignoring unknown CosLifeCycle criterion: "<<criteria[i].name);
00283     }
00284   } // end loop for(i)
00285   
00286   return result.release();
00287 }
00288 
00289 
00290 CosLifeCycle::Criteria EventChannelFactory_i::extract(
00291   const char*                   name,
00292   const CosLifeCycle::Criteria& from
00293 ) const
00294 {
00295   CosLifeCycle::Criteria result;
00296   result.length(0);
00297   for(CORBA::ULong i=0; i<from.length(); i++)
00298   {
00299     if(strcmp(from[i].name,name) == 0)
00300     {
00301       result.length(1);
00302       result[0]=from[i];
00303       break;
00304     }
00305   }
00306   return result;
00307 }
00308 
00309 
00310 void
00311 EventChannelFactory_i::output(ostream &os)
00312 {
00313   os<<"ecf port="<<_port;
00314   if(!_endPointNoListen.empty())
00315       os<<" endPointNoListen="<<_endPointNoListen;
00316   os<<" ;;\n";
00317   _channels.output(os);
00318 }
00319 
00320 
00321 }; // end namespace OmniEvents

Generated on Mon Jan 9 03:52:13 2006 for OmniEvents by  doxygen 1.4.6