Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

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") == 0)
00204     {
00205       CORBA::ULong pullRetryPeriod;
00206       if(! (criteria[i].value >>= pullRetryPeriod))
00207           throw InvalidCriteria(extract("PullRetryPeriod",criteria));
00208       if(pullRetryPeriod <= 0)
00209           throw CannotMeetCriteria(extract("PullRetryPeriod",criteria));
00210       result->addattr("PullRetryPeriod",pullRetryPeriod);
00211     }
00212     else if(strcmp(criteria[i].name, "MaxQueueLength") == 0)
00213     {
00214       CORBA::ULong maxQueueLength;
00215       if(! (criteria[i].value >>= maxQueueLength))
00216           throw InvalidCriteria(extract("MaxQueueLength",criteria));
00217       if(maxQueueLength > 0)
00218           result->addattr("MaxQueueLength",maxQueueLength);
00219       else
00220           DB(10,"Ignoring CosLifeCycle criterion: MaxQueueLength=0");
00221     }
00222     else if(strcmp(criteria[i].name, "MaxNumProxies") == 0)
00223     {
00224       CORBA::ULong maxNumProxies;
00225       if(! (criteria[i].value >>= maxNumProxies))
00226           throw InvalidCriteria(extract("MaxNumProxies",criteria));
00227       if(maxNumProxies > 0)
00228           result->addattr("MaxNumProxies",maxNumProxies);
00229       else
00230           DB(10,"Ignoring CosLifeCycle criterion: MaxNumProxies=0");
00231     }
00232     else if(strcmp(criteria[i].name, "CyclePeriod_ns") == 0)
00233     {
00234       CORBA::ULong cyclePeriod_ns;
00235       if(! (criteria[i].value >>= cyclePeriod_ns))
00236           throw InvalidCriteria(extract("CyclePeriod_ns",criteria));
00237       if(cyclePeriod_ns > 0)
00238           result->addattr("CyclePeriod_ns",cyclePeriod_ns);
00239       else
00240           DB(10,"Ignoring CosLifeCycle criterion: CyclePeriod_ns=0");
00241     }
00242     else if(strcmp(criteria[i].name, "InsName") == 0)
00243     {
00244       const char* insName;
00245       if(! (criteria[i].value >>= insName))
00246           throw InvalidCriteria(extract("InsName",criteria));
00247       if(insName && insName[0])
00248           result->addattr(string("InsName=")+insName);
00249       else
00250           DB(10,"Ignoring empty CosLifeCycle criterion: InsName");
00251     }
00252     else if(strcmp(criteria[i].name, "FilterId") == 0)
00253     {
00254       const char* repositoryId;
00255       if(! (criteria[i].value >>= repositoryId))
00256           throw InvalidCriteria(extract("FilterId",criteria));
00257       if(repositoryId && repositoryId[0])
00258           result->addattr(string("FilterId=")+repositoryId);
00259       else
00260           DB(10,"Ignoring empty CosLifeCycle criterion: FilterId");
00261     }
00262     else if(strcmp(criteria[i].name, "MaxEventsPerConsumer") == 0)
00263     {
00264       DB(10,"Ignoring obsolete CosLifeCycle criterion: MaxEventsPerConsumer");
00265     }
00266     else
00267     {
00268       DB(10,"Ignoring unknown CosLifeCycle criterion: "<<criteria[i].name);
00269     }
00270   } // end loop for(i)
00271   
00272   return result.release();
00273 }
00274 
00275 
00276 CosLifeCycle::Criteria EventChannelFactory_i::extract(
00277   const char*                   name,
00278   const CosLifeCycle::Criteria& from
00279 ) const
00280 {
00281   CosLifeCycle::Criteria result;
00282   result.length(0);
00283   for(CORBA::ULong i=0; i<from.length(); i++)
00284   {
00285     if(strcmp(from[i].name,name) == 0)
00286     {
00287       result.length(1);
00288       result[0]=from[i];
00289       break;
00290     }
00291   }
00292   return result;
00293 }
00294 
00295 
00296 void
00297 EventChannelFactory_i::output(ostream &os)
00298 {
00299   os<<"ecf port="<<_port;
00300   if(!_endPointNoListen.empty())
00301       os<<" endPointNoListen="<<_endPointNoListen;
00302   os<<" ;;\n";
00303   _channels.output(os);
00304 }
00305 
00306 
00307 }; // end namespace OmniEvents

Generated on Fri Oct 8 15:52:51 2004 for OmniEvents by doxygen1.2.15