bes  Updated for version 3.19.1
BESRequestHandlerList.cc
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 BESRequestHandlerList::add_handler(const string &handler_name, BESRequestHandler *handler_object)
50 {
51  if (find_handler(handler_name) == 0) {
52  _handler_list[handler_name] = handler_object;
53  return true;
54  }
55  return false;
56 }
57 
71 BESRequestHandlerList::remove_handler(const string &handler_name)
72 {
73  BESRequestHandler *ret = 0;
74  BESRequestHandlerList::Handler_iter i;
75  i = _handler_list.find(handler_name);
76  if (i != _handler_list.end()) {
77  ret = (*i).second;
78  _handler_list.erase(i);
79  }
80  return ret;
81 }
82 
90 BESRequestHandlerList::find_handler(const string &handler_name)
91 {
92  BESRequestHandlerList::Handler_citer i;
93  i = _handler_list.find(handler_name);
94  if (i != _handler_list.end()) {
95  return (*i).second;
96  }
97  return 0;
98 }
99 
107 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_first_handler()
108 {
109  return _handler_list.begin();
110 }
111 
117 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_last_handler()
118 {
119  return _handler_list.end();
120 }
121 
130 {
131  string ret = "";
132  bool first_name = true;
133  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
134  for (; i != _handler_list.end(); i++) {
135  if (!first_name) ret += ", ";
136  ret += (*i).first;
137  first_name = false;
138  }
139  return ret;
140 }
141 
163 {
164  dhi.first_container();
165  while (dhi.container) {
166  execute_current(dhi);
167  dhi.next_container();
168  }
169 }
170 
190 {
191  BESRequestHandlerList::Handler_citer i = get_first_handler();
192  BESRequestHandlerList::Handler_citer ie = get_last_handler();
193  for (; i != ie; i++) {
194  BESRequestHandler *rh = (*i).second;
195  p_request_handler p = rh->find_handler(dhi.action);
196  if (p) {
197  p(dhi);
198  }
199  }
200 }
201 
223 {
224  dhi.first_container();
225  execute_current(dhi);
226 }
227 
245 {
246  if (dhi.container) {
247  // FIXME: This needs to happen here, but really should be done
248  // in the get_container_type method in the container class if it
249  // needs to happen. But those methods are not virtual and would
250  // require a release of all modules.
251  dhi.container->access();
252 
253  // TODO Do not need to use .c_str(). jhrg 2/20/15
255  if (rh) {
256  p_request_handler p = rh->find_handler(dhi.action);
257  // if we can't find the function, see if there is a catch all
258  // function that handles or redirects the request.
259  //
260  // TODO NB: There are no instances of catch.all handlers.
261  // jhrg 2/20/15
262  if (!p) {
263  p = rh->find_handler( BES_REQUEST_HANDLER_CATCH_ALL);
264  }
265 
266  if (p) {
267  p(dhi); // This is where the request handler is called
268 
269  if (dhi.container) {
270  // This is (likely) for reporting. May not be used... jhrg 2/20/15
271  string c_list = dhi.data[REAL_NAME_LIST];
272  if (!c_list.empty()) c_list += ", ";
273  c_list += dhi.container->get_real_name();
274  dhi.data[REAL_NAME_LIST] = c_list;
275  }
276  }
277  else {
278  // TODO This should not be an internal error - it's really a configuration error
279  // jhrg 2/20/15
280  string se = "Request handler \"" + dhi.container->get_container_type()
281  + "\" does not handle the response type \"" + dhi.action + "\"";
282  throw BESInternalError(se, __FILE__, __LINE__);
283  }
284  }
285  else {
286  string se = "The data handler \"" + dhi.container->get_container_type() + "\" does not exist";
287  throw BESInternalError(se, __FILE__, __LINE__);
288  }
289  }
290 }
291 
299 void BESRequestHandlerList::dump(ostream &strm) const
300 {
301  strm << BESIndent::LMarg << "BESRequestHandlerList::dump - (" << (void *) this << ")" << endl;
302  BESIndent::Indent();
303  if (_handler_list.size()) {
304  strm << BESIndent::LMarg << "registered handlers:" << endl;
305  BESIndent::Indent();
306  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
307  BESRequestHandlerList::Handler_citer ie = _handler_list.end();
308  for (; i != ie; i++) {
309  BESRequestHandler *rh = (*i).second;
310  rh->dump(strm);
311  }
312  BESIndent::UnIndent();
313  }
314  else {
315  strm << BESIndent::LMarg << "registered handlers: none" << endl;
316  }
317  BESIndent::UnIndent();
318 }
319 
321 BESRequestHandlerList::TheList()
322 {
323  if (_instance == 0) {
324  _instance = new BESRequestHandlerList;
325  }
326  return _instance;
327 }
328 
virtual Handler_citer get_first_handler()
return an iterator pointing to the first request handler in the list
virtual void dump(ostream &strm) const
dumps information about this object
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...
maintains the list of registered request handlers for this server
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
virtual void execute_each(BESDataHandlerInterface &dhi)
for each container in the given data handler interface, execute the given request ...
virtual void execute_all(BESDataHandlerInterface &dhi)
for all of the registered request handlers, execute the given request
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.
virtual void dump(ostream &strm) const
dumps information about this object
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
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:161
virtual void execute_current(BESDataHandlerInterface &dhi)
Execute a single method for the current container that will fill in the response object rather than i...
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:208
void first_container()
set the container pointer to the first container in the containers list
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. das, dds
BESContainer * container
pointer to current container in this interface
virtual BESRequestHandler * remove_handler(const string &handler_name)
remove and return the specified request handler