BESServiceRegistry.cc

Go to the documentation of this file.
00001 // BESServiceRegistry.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #include "BESServiceRegistry.h"
00034 #include "BESInfo.h"
00035 #include "BESInternalError.h"
00036 
00037 BESServiceRegistry *BESServiceRegistry::_instance = 0 ;
00038 
00039 BESServiceRegistry::BESServiceRegistry()
00040 {
00041 }
00042 
00043 BESServiceRegistry::~BESServiceRegistry()
00044 {
00045 }
00046 
00055 void
00056 BESServiceRegistry::add_service( const string &name ) 
00057 {
00058     map<string,map<string,service_cmd> >::iterator i = _services.find( name ) ;
00059     if( i == _services.end() )
00060     {
00061         map<string,service_cmd> cmds ;
00062         _services[name] = cmds ;
00063     }
00064     else
00065     {
00066         string err = (string)"The service " + name
00067                      + " has already been registered" ;
00068         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00069     }
00070 }
00071 
00086 void
00087 BESServiceRegistry::add_to_service( const string &service,
00088                                     const string &cmd,
00089                                     const string &cmd_descript,
00090                                     const string &format )
00091 {
00092     map<string,map<string,service_cmd> >::iterator si ;
00093     si = _services.find( service ) ;
00094     if( si != _services.end() )
00095     {
00096         map<string,service_cmd>::const_iterator ci ;
00097         ci = (*si).second.find( cmd ) ;
00098         if( ci != (*si).second.end() )
00099         {
00100             string err = (string)"Attempting to add command "
00101                          + (*ci).first + " to the service "
00102                          + service + ", command alrady exists" ;
00103             throw BESInternalError( err, __FILE__, __LINE__ ) ;
00104         }
00105         service_cmd sc ;
00106         sc._description = cmd_descript ;
00107         sc._formats[format] = format ;
00108         (*si).second[cmd] = sc ;
00109     }
00110     else
00111     {
00112         string err = (string)"Attempting to add commands to the service "
00113                      + service + " that has not yet been registered" ;
00114         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00115     }
00116 }
00117 
00126 void
00127 BESServiceRegistry::add_format( const string &service,
00128                                 const string &cmd,
00129                                 const string &format )
00130 {
00131     map<string,map<string,service_cmd> >::iterator si ;
00132     si = _services.find( service ) ;
00133     if( si != _services.end() )
00134     {
00135         map<string,service_cmd>::iterator ci = (*si).second.find( cmd ) ;
00136         if( ci != (*si).second.end() )
00137         {
00138             map<string,string>::iterator fi ;
00139             fi = (*ci).second._formats.find( format ) ;
00140             if( fi == (*ci).second._formats.end() )
00141             {
00142                 (*ci).second._formats[format] = format ;
00143             }
00144             else
00145             {
00146                 string err = (string)"Attempting to add format "
00147                              + format + " to command " + cmd
00148                              + " for service " + service
00149                              + " where the format has already been registered" ;
00150                 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00151             }
00152         }
00153         else
00154         {
00155             string err = (string)"Attempting to add a format " + format
00156                          + " to command " + cmd + " for service " + service
00157                          + " where the command has not been registered" ;
00158             throw BESInternalError( err, __FILE__, __LINE__ ) ;
00159         }
00160     }
00161     else
00162     {
00163         string err = (string)"Attempting to add a format " + format
00164                      + " to command " + cmd + " for a service " + service
00165                      + " that has not been registered" ;
00166         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00167     }
00168 }
00169 
00178 void
00179 BESServiceRegistry::remove_service( const string &service )
00180 {
00181     map<string,map<string,service_cmd> >::iterator i ;
00182     i = _services.find( service ) ;
00183     if( i != _services.end() )
00184     {
00185         // erase the service from the registry
00186         _services.erase( i ) ;
00187 
00188         // remove the service from the _handles list as well, so that if
00189         // asked, the handlers no longer handler the service because it no
00190         // longer exists.
00191         map<string,map<string,string> >::iterator hi = _handles.begin() ;
00192         map<string,map<string,string> >::iterator he = _handles.end() ;
00193         for( ; hi != he; hi++ )
00194         {
00195             map<string,string>::iterator hsi = (*hi).second.find( service ) ;
00196             if( hsi != (*hi).second.end() )
00197             {
00198                 (*hi).second.erase( hsi ) ;
00199             }
00200         }
00201     }
00202 }
00203 
00215 bool
00216 BESServiceRegistry::service_available( const string &service,
00217                                        const string &cmd,
00218                                        const string &format )
00219 {
00220     bool isit = false ;
00221     map<string,map<string,service_cmd> >::iterator si ;
00222     si = _services.find( service ) ;
00223     if( si != _services.end() )
00224     {
00225         if( !cmd.empty() )
00226         {
00227             map<string,service_cmd>::iterator ci = (*si).second.find( cmd ) ;
00228             if( ci != (*si).second.end() )
00229             {
00230                 if( !format.empty() )
00231                 {
00232                     map<string,string>::iterator fi ;
00233                     fi = (*ci).second._formats.find( format ) ;
00234                     if( fi != (*ci).second._formats.end() )
00235                     {
00236                         isit = true ;
00237                     }
00238                 }
00239                 else
00240                 {
00241                     isit = true ;
00242                 }
00243             }
00244         }
00245         else
00246         {
00247             isit = true ;
00248         }
00249     }
00250     return isit ;
00251 }
00252 
00264 void
00265 BESServiceRegistry::handles_service( const string &handler,
00266                                      const string &service )
00267 {
00268     map<string,map<string,service_cmd> >::iterator si ;
00269     si = _services.find( service ) ;
00270     if( si == _services.end() )
00271     {
00272         string err = (string)"Registering a handler to handle service "
00273                      + service + " that has not yet been registered" ;
00274         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00275     }
00276 
00277     map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
00278     if( hi == _handles.end() )
00279     {
00280         map<string,string> services ;
00281         services[service] = service ;
00282         _handles[handler] = services ;
00283     }
00284     else
00285     {
00286         map<string,string>::iterator ci = (*hi).second.find( service ) ;
00287         if( ci == (*hi).second.end() )
00288         {
00289             (*hi).second[service] = service ;
00290         }
00291     }
00292 }
00293 
00302 bool
00303 BESServiceRegistry::does_handle_service( const string &handler,
00304                                          const string &service )
00305 {
00306     bool handled = false ;
00307     map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
00308     if( hi != _handles.end() )
00309     {
00310         map<string,string>::iterator si = (*hi).second.find( service ) ;
00311         if( si != (*hi).second.end() )
00312         {
00313             handled = true ;
00314         }
00315     }
00316     return handled ;
00317 }
00318 
00327 void
00328 BESServiceRegistry::services_handled( const string &handler,
00329                                       list<string> &services )
00330 {
00331     map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
00332     if( hi != _handles.end() )
00333     {
00334         map<string,string>::const_iterator si = (*hi).second.begin() ;
00335         map<string,string>::const_iterator se = (*hi).second.end() ;
00336         for( ; si != se; si++ )
00337         {
00338             services.push_back( (*si).second ) ;
00339         }
00340     }
00341 }
00342 
00351 void
00352 BESServiceRegistry::show_services( BESInfo &info )
00353 {
00354     map<string,map<string,service_cmd> >::iterator si = _services.begin() ;
00355     map<string,map<string,service_cmd> >::iterator se = _services.end() ;
00356     for( ; si != se; si++ )
00357     {
00358         map<string,string> props ;
00359         props["name"] = (*si).first ;
00360         info.begin_tag( "serviceDescription", &props ) ;
00361         map<string,service_cmd>::iterator ci = (*si).second.begin() ;
00362         map<string,service_cmd>::iterator ce = (*si).second.end() ;
00363         for( ; ci != ce; ci++ )
00364         {
00365             map<string,string> cprops ;
00366             cprops["name"] = (*ci).first ;
00367             info.begin_tag( "command", &cprops ) ;
00368             info.add_tag( "description", (*ci).second._description ) ;
00369             map<string,string>::iterator fi = (*ci).second._formats.begin() ;
00370             map<string,string>::iterator fe = (*ci).second._formats.end() ;
00371             for( ; fi != fe; fi++ )
00372             {
00373                 map<string,string> fprops ;
00374                 fprops["name"] = (*fi).first ;
00375                 info.add_tag( "format", "", &fprops ) ;
00376             }
00377             info.end_tag( "command" ) ;
00378         }
00379         info.end_tag( "serviceDescription" ) ;
00380     }
00381 }
00382 
00390 void
00391 BESServiceRegistry::dump( ostream &strm ) const
00392 {
00393     strm << BESIndent::LMarg << "BESServiceRegistry::dump - ("
00394                              << (void *)this << ")" << endl ;
00395     BESIndent::Indent() ;
00396     strm << BESIndent::LMarg << "registered services" << endl ;
00397     BESIndent::Indent() ;
00398     map<string,map<string,service_cmd> >::const_iterator si ;
00399     si = _services.begin() ;
00400     map<string,map<string,service_cmd> >::const_iterator se ;
00401     se = _services.end() ;
00402     for( ; si != se; si++ )
00403     {
00404         strm << BESIndent::LMarg << (*si).first << endl ;
00405         BESIndent::Indent() ;
00406         map<string,service_cmd>::const_iterator ci = (*si).second.begin() ;
00407         map<string,service_cmd>::const_iterator ce = (*si).second.end() ;
00408         for( ; ci != ce; ci++ )
00409         {
00410             strm << BESIndent::LMarg << (*ci).first << endl ;
00411             BESIndent::Indent() ;
00412             strm << BESIndent::LMarg << "description: "
00413                  << (*ci).second._description << endl ;
00414             strm << BESIndent::LMarg << "formats:" << endl ;
00415             BESIndent::Indent() ;
00416             map<string,string>::const_iterator fi ;
00417             fi = (*ci).second._formats.begin() ;
00418             map<string,string>::const_iterator fe ;
00419             fe = (*ci).second._formats.end() ;
00420             for( ; fi != fe; fi++ )
00421             {
00422                 strm << BESIndent::LMarg << (*fi).first << endl ;
00423             }
00424             BESIndent::UnIndent() ;
00425             BESIndent::UnIndent() ;
00426         }
00427         BESIndent::UnIndent() ;
00428     }
00429     BESIndent::UnIndent() ;
00430     strm << BESIndent::LMarg << "services provided by handler" << endl ;
00431     BESIndent::Indent() ;
00432     map<string,map<string,string> >::const_iterator hi = _handles.begin() ;
00433     map<string,map<string,string> >::const_iterator he = _handles.end() ;
00434     for( ; hi != he; hi++ )
00435     {
00436         strm << BESIndent::LMarg << (*hi).first ;
00437         map<string,string>::const_iterator hsi = (*hi).second.begin() ;
00438         map<string,string>::const_iterator hse = (*hi).second.end() ;
00439         bool isfirst = true ;
00440         for( ; hsi != hse; hsi++ )
00441         {
00442             if( !isfirst ) strm << ", " ;
00443             else strm << ": " ;
00444             strm << (*hsi).first ;
00445             isfirst = false ;
00446         }
00447         strm << endl ;
00448     }
00449     BESIndent::UnIndent() ;
00450     BESIndent::UnIndent() ;
00451 }
00452 
00453 BESServiceRegistry *
00454 BESServiceRegistry::TheRegistry()
00455 {
00456     if( _instance == 0 )
00457     {
00458         _instance = new BESServiceRegistry ;
00459     }
00460     return _instance ;
00461 }
00462 

Generated on Sat Aug 22 06:04:40 2009 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.6.0