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 
00052 void
00053 BESServiceRegistry::add_service( const string &name ) 
00054 {
00055     map<string,map<string,service_cmd> >::iterator i = _services.find( name ) ;
00056     if( i == _services.end() )
00057     {
00058         map<string,service_cmd> cmds ;
00059         _services[name] = cmds ;
00060     }
00061     else
00062     {
00063         string err = (string)"The service " + name
00064                      + " has already been registered" ;
00065         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00066     }
00067 }
00068 
00083 void
00084 BESServiceRegistry::add_to_service( const string &service,
00085                                     const string &cmd,
00086                                     const string &cmd_descript,
00087                                     const string &format )
00088 {
00089     map<string,map<string,service_cmd> >::iterator si ;
00090     si = _services.find( service ) ;
00091     if( si != _services.end() )
00092     {
00093         map<string,service_cmd>::const_iterator ci ;
00094         ci = (*si).second.find( cmd ) ;
00095         if( ci != (*si).second.end() )
00096         {
00097             string err = (string)"Attempting to add command "
00098                          + (*ci).first + " to the service "
00099                          + service + ", command alrady exists" ;
00100             throw BESInternalError( err, __FILE__, __LINE__ ) ;
00101         }
00102         service_cmd sc ;
00103         sc._description = cmd_descript ;
00104         sc._formats[format] = format ;
00105         (*si).second[cmd] = sc ;
00106     }
00107     else
00108     {
00109         string err = (string)"Attempting to add commands to the service "
00110                      + service + " that has not yet been registered" ;
00111         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00112     }
00113 }
00114 
00123 void
00124 BESServiceRegistry::add_format( const string &service,
00125                                 const string &cmd,
00126                                 const string &format )
00127 {
00128     map<string,map<string,service_cmd> >::iterator si ;
00129     si = _services.find( service ) ;
00130     if( si != _services.end() )
00131     {
00132         map<string,service_cmd>::iterator ci = (*si).second.find( cmd ) ;
00133         if( ci != (*si).second.end() )
00134         {
00135             map<string,string>::iterator fi ;
00136             fi = (*ci).second._formats.find( format ) ;
00137             if( fi == (*ci).second._formats.end() )
00138             {
00139                 (*ci).second._formats[format] = format ;
00140             }
00141             else
00142             {
00143                 string err = (string)"Attempting to add format "
00144                              + format + " to command " + cmd
00145                              + " for service " + service
00146                              + " where the format has already been registered" ;
00147                 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00148             }
00149         }
00150         else
00151         {
00152             string err = (string)"Attempting to add a format " + format
00153                          + " to command " + cmd + " for service " + service
00154                          + " where the command has not been registered" ;
00155             throw BESInternalError( err, __FILE__, __LINE__ ) ;
00156         }
00157     }
00158     else
00159     {
00160         string err = (string)"Attempting to add a format " + format
00161                      + " to command " + cmd + " for a service " + service
00162                      + " that has not been registered" ;
00163         throw BESInternalError( err, __FILE__, __LINE__ ) ;
00164     }
00165 }
00166 
00175 void
00176 BESServiceRegistry::remove_service( const string &service )
00177 {
00178     map<string,map<string,service_cmd> >::iterator i ;
00179     i = _services.find( service ) ;
00180     if( i != _services.end() )
00181     {
00182         // erase the service from the registry
00183         _services.erase( i ) ;
00184 
00185         // remove the service from the _handles list as well, so that if
00186         // asked, the handlers no longer handler the service because it no
00187         // longer exists.
00188         map<string,map<string,string> >::iterator hi = _handles.begin() ;
00189         map<string,map<string,string> >::iterator he = _handles.end() ;
00190         for( ; hi != he; hi++ )
00191         {
00192             map<string,string>::iterator hsi = (*hi).second.find( service ) ;
00193             if( hsi != (*hi).second.end() )
00194             {
00195                 (*hi).second.erase( hsi ) ;
00196             }
00197         }
00198     }
00199 }
00200 
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 Thu Sep 16 15:20:30 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.4.7