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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 ;
320  BESIndent::Indent() ;
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