OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESRequestHandlerList.cc
Go to the documentation of this file.
1 // BESRequestHandlerList.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include "BESRequestHandlerList.h"
34 #include "BESRequestHandler.h"
35 #include "BESInternalError.h"
36 #include "BESDataNames.h"
37 
38 BESRequestHandlerList *BESRequestHandlerList::_instance = 0 ;
39 
49 bool
50 BESRequestHandlerList::add_handler( const string &handler_name,
51  BESRequestHandler *handler_object )
52 {
53  if( find_handler( handler_name ) == 0 )
54  {
55  _handler_list[handler_name] = handler_object ;
56  return true ;
57  }
58  return false ;
59 }
60 
74 BESRequestHandlerList::remove_handler( const string &handler_name )
75 {
76  BESRequestHandler *ret = 0 ;
78  i = _handler_list.find( handler_name ) ;
79  if( i != _handler_list.end() )
80  {
81  ret = (*i).second;
82  _handler_list.erase( i ) ;
83  }
84  return ret ;
85 }
86 
94 BESRequestHandlerList::find_handler( const string &handler_name )
95 {
97  i = _handler_list.find( handler_name ) ;
98  if( i != _handler_list.end() )
99  {
100  return (*i).second;
101  }
102  return 0 ;
103 }
104 
114 {
115  return _handler_list.begin() ;
116 }
117 
125 {
126  return _handler_list.end() ;
127 }
128 
136 string
138 {
139  string ret = "";
140  bool first_name = true ;
141  BESRequestHandlerList::Handler_citer i = _handler_list.begin() ;
142  for( ; i != _handler_list.end(); i++ )
143  {
144  if( !first_name )
145  ret += ", " ;
146  ret += (*i).first ;
147  first_name = false ;
148  }
149  return ret ;
150 }
151 
172 void
174 {
175  dhi.first_container() ;
176  while( dhi.container )
177  {
178  execute_current( dhi ) ;
179  dhi.next_container() ;
180  }
181 }
182 
198 void
200 {
203  for( ; i != ie; i++ )
204  {
205  BESRequestHandler *rh = (*i).second ;
206  p_request_handler p = rh->find_handler( dhi.action ) ;
207  if( p )
208  {
209  p( dhi ) ;
210  }
211  }
212 }
213 
232 void
234 {
235  dhi.first_container() ;
236  execute_current( dhi ) ;
237 }
238 
255 void
257 {
258  if( dhi.container )
259  {
260  // FIXME: This needs to happen here, but really should be done
261  // in the get_container_type method in the container class if it
262  // needs to happen. But those methods are not virtual and would
263  // require a release of all modules.
264  dhi.container->access() ;
265 
266  BESRequestHandler *rh = find_handler( (dhi.container->get_container_type()).c_str() ) ;
267  if( rh )
268  {
269  p_request_handler p = rh->find_handler( dhi.action ) ;
270  // if we can't find the function, see if there is a catch all
271  // function that handles or redirects the request.
272  if( !p )
273  {
275  }
276 
277  if( p )
278  {
279  p( dhi ) ;
280  if( dhi.container )
281  {
282  string c_list = dhi.data[REAL_NAME_LIST] ;
283  if( !c_list.empty() )
284  c_list += ", " ;
285  c_list += dhi.container->get_real_name() ;
286  dhi.data[REAL_NAME_LIST] = c_list ;
287  }
288  } else {
289  string se = "Request handler \""
291  + "\" does not handle the response type \""
292  + dhi.action + "\"" ;
293  throw BESInternalError( se, __FILE__, __LINE__ ) ;
294  }
295  } else {
296  string se = "The data handler \""
298  + "\" does not exist" ;
299  throw BESInternalError( se, __FILE__, __LINE__ ) ;
300  }
301  }
302 }
303 
311 void
312 BESRequestHandlerList::dump( ostream &strm ) const
313 {
314  strm << BESIndent::LMarg << "BESRequestHandlerList::dump - ("
315  << (void *)this << ")" << endl ;
317  if( _handler_list.size() )
318  {
319  strm << BESIndent::LMarg << "registered handlers:" << endl ;
321  BESRequestHandlerList::Handler_citer i = _handler_list.begin() ;
322  BESRequestHandlerList::Handler_citer ie = _handler_list.end() ;
323  for( ; i != ie; i++ )
324  {
325  BESRequestHandler *rh = (*i).second ;
326  rh->dump( strm ) ;
327  }
329  }
330  else
331  {
332  strm << BESIndent::LMarg << "registered handlers: none" << endl ;
333  }
335 }
336 
339 {
340  if( _instance == 0 )
341  {
342  _instance = new BESRequestHandlerList ;
343  }
344  return _instance ;
345 }
346 
virtual Handler_citer get_first_handler()
return an iterator pointing to the first request handler in the list
exception thrown if inernal error encountered
virtual bool add_handler(const string &handler_name, BESRequestHandler *handler)
add a request handler to the list of registered handlers for this server
void next_container()
set the container pointer to the next * container in the list, null if at the end or no containers in...
#define REAL_NAME_LIST
Definition: BESDataNames.h:57
maintains the list of registered request handlers for this server
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:170
virtual void dump(ostream &strm) const
dumps information about this object
bool(* p_request_handler)(BESDataHandlerInterface &)
static void Indent()
Definition: BESIndent.cc:38
virtual string access()=0
returns the true name of this container
virtual BESRequestHandler * find_handler(const string &handler_name)
find and return the specified request handler
map< string, BESRequestHandler * >::const_iterator Handler_citer
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
virtual void execute_each(BESDataHandlerInterface &dhi)
for each container in the given data handler interface, execute the given request ...
map< string, BESRequestHandler * >::iterator Handler_iter
virtual void execute_all(BESDataHandlerInterface &dhi)
for all of the registered request handlers, execute the given request
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:141
virtual void execute_once(BESDataHandlerInterface &dhi)
Execute a single method that will fill in the response object rather than iterating over the list of ...
virtual string get_handler_names()
Returns a comma separated string of request handlers registered with the server.
Represents a specific data type request handler.
static BESRequestHandlerList * TheList()
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
virtual Handler_citer get_last_handler()
return a constant iterator pointing to the end of the list
virtual void execute_current(BESDataHandlerInterface &dhi)
Execute a single method for the current container that will fill in the response object rather than i...
void first_container()
set the container pointer to the first container in the containers list
static void UnIndent()
Definition: BESIndent.cc:44
#define BES_REQUEST_HANDLER_CATCH_ALL
virtual void dump(ostream &strm) const
dumps information about this object
virtual p_request_handler find_handler(const string &handler_name)
find the method that can handle the specified response object type
string action
the response object requested, e.g.
BESContainer * container
pointer to current container in this interface
virtual BESRequestHandler * remove_handler(const string &handler_name)
remove and return the specified request handler