bes  Updated for version 3.20.5
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 "config.h"
34 
35 #include "BESRequestHandlerList.h"
36 #include "BESRequestHandler.h"
37 #include "BESInternalError.h"
38 
39 BESRequestHandlerList *BESRequestHandlerList::_instance = 0;
40 
50 bool BESRequestHandlerList::add_handler(const string &handler_name, BESRequestHandler *handler_object)
51 {
52  if (find_handler(handler_name) == 0) {
53  _handler_list[handler_name] = handler_object;
54  return true;
55  }
56  return false;
57 }
58 
72 BESRequestHandlerList::remove_handler(const string &handler_name)
73 {
74  BESRequestHandler *ret = 0;
75  BESRequestHandlerList::Handler_iter i;
76  i = _handler_list.find(handler_name);
77  if (i != _handler_list.end()) {
78  ret = (*i).second;
79  _handler_list.erase(i);
80  }
81  return ret;
82 }
83 
91 BESRequestHandlerList::find_handler(const string &handler_name)
92 {
93  BESRequestHandlerList::Handler_citer i;
94  i = _handler_list.find(handler_name);
95  if (i != _handler_list.end()) {
96  return (*i).second;
97  }
98  return 0;
99 }
100 
108 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_first_handler()
109 {
110  return _handler_list.begin();
111 }
112 
118 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_last_handler()
119 {
120  return _handler_list.end();
121 }
122 
131 {
132  string ret = "";
133  bool first_name = true;
134  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
135  for (; i != _handler_list.end(); i++) {
136  if (!first_name) ret += ", ";
137  ret += (*i).first;
138  first_name = false;
139  }
140  return ret;
141 }
142 
164 {
165  dhi.first_container();
166  while (dhi.container) {
167  execute_current(dhi);
168  dhi.next_container();
169  }
170 }
171 
191 {
192  BESRequestHandlerList::Handler_citer i = get_first_handler();
193  BESRequestHandlerList::Handler_citer ie = get_last_handler();
194  for (; i != ie; i++) {
195  BESRequestHandler *rh = (*i).second;
196  p_request_handler_method p = rh->find_method(dhi.action);
197  if (p) {
198  p(dhi);
199  }
200  }
201 }
202 
203 #if 0
204 
224 void BESRequestHandlerList::execute_once(BESDataHandlerInterface &dhi)
225 {
226  dhi.first_container();
227  execute_current(dhi);
228 }
229 #endif
230 
248 {
249  if (dhi.container) {
250  // Patrick's comment: This needs to happen here, but really should be done
251  // in the get_container_type method in the container class if it
252  // needs to happen.
253  //
254  // This call will, for BESFileContainer, decompress and cache compressed files,
255  // changing their extensions from, e.g., '.gz' to '.h5' and enabling the
256  // get_container_type() method to function correctly. jhrg 5/31/18
257  dhi.container->access();
258 
259  // Given the kind of thing in the DHI's container (netcdf file, ...) find the
260  // RequestHandler that understands that and then find the method in that handler
261  // that can process the DHI's action.
263  if (!rh)
264  throw BESInternalError(string("The data handler '") + dhi.container->get_container_type() + "' does not exist",
265  __FILE__, __LINE__);
266 
267  p_request_handler_method request_handler_method = rh->find_method(dhi.action);
268  if (!request_handler_method) {
269  throw BESInternalError(string("Request handler for '") + dhi.container->get_container_type()
270  + "' does not handle the response type '" + dhi.action + "'", __FILE__, __LINE__);
271  }
272 
273  request_handler_method(dhi); // This is where the request handler method is called
274  }
275 }
276 
284 void BESRequestHandlerList::dump(ostream &strm) const
285 {
286  strm << BESIndent::LMarg << "BESRequestHandlerList::dump - (" << (void *) this << ")" << endl;
287  BESIndent::Indent();
288  if (_handler_list.size()) {
289  strm << BESIndent::LMarg << "registered handlers:" << endl;
290  BESIndent::Indent();
291  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
292  BESRequestHandlerList::Handler_citer ie = _handler_list.end();
293  for (; i != ie; i++) {
294  BESRequestHandler *rh = (*i).second;
295  rh->dump(strm);
296  }
297  BESIndent::UnIndent();
298  }
299  else {
300  strm << BESIndent::LMarg << "registered handlers: none" << endl;
301  }
302  BESIndent::UnIndent();
303 }
304 
306 BESRequestHandlerList::TheList()
307 {
308  if (_instance == 0) {
309  _instance = new BESRequestHandlerList;
310  }
311  return _instance;
312 }
313 
BESRequestHandler
Represents a specific data type request handler.
Definition: BESRequestHandler.h:77
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:79
BESRequestHandlerList::remove_handler
virtual BESRequestHandler * remove_handler(const std::string &handler_name)
remove and return the specified request handler
Definition: BESRequestHandlerList.cc:72
BESRequestHandlerList::execute_current
virtual void execute_current(BESDataHandlerInterface &dhi)
Execute a single method for the current container that will fill in the response object rather than i...
Definition: BESRequestHandlerList.cc:247
BESRequestHandler::find_method
virtual p_request_handler_method find_method(const string &name)
find the method that can handle the specified response object type
Definition: BESRequestHandler.cc:87
BESRequestHandlerList::execute_all
virtual void execute_all(BESDataHandlerInterface &dhi)
for all of the registered request handlers, execute the given request
Definition: BESRequestHandlerList.cc:190
BESContainer::access
virtual string access()=0
returns the true name of this container
BESDataHandlerInterface::next_container
void next_container()
set the container pointer to the next * container in the list, null if at the end or no containers in...
Definition: BESDataHandlerInterface.h:150
BESRequestHandlerList
The list of registered request handlers for this server; a singleton.
Definition: BESRequestHandlerList.h:69
BESRequestHandlerList::execute_each
virtual void execute_each(BESDataHandlerInterface &dhi)
for each container in the given data handler interface, execute the given request
Definition: BESRequestHandlerList.cc:163
BESRequestHandlerList::add_handler
virtual bool add_handler(const std::string &handler_name, BESRequestHandler *handler)
add a request handler to the list of registered handlers for this server
Definition: BESRequestHandlerList.cc:50
BESRequestHandlerList::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESRequestHandlerList.cc:284
BESContainer::get_container_type
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:235
BESInternalError
exception thrown if inernal error encountered
Definition: BESInternalError.h:43
BESRequestHandlerList::get_last_handler
virtual Handler_citer get_last_handler()
return a constant iterator pointing to the end of the list
Definition: BESRequestHandlerList.cc:118
BESRequestHandler::dump
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESRequestHandler.cc:124
BESRequestHandlerList::get_first_handler
virtual Handler_citer get_first_handler()
return an iterator pointing to the first request handler in the list
Definition: BESRequestHandlerList.cc:108
BESDataHandlerInterface::action
string action
the response object requested, e.g. das, dds
Definition: BESDataHandlerInterface.h:83
BESDataHandlerInterface::first_container
void first_container()
set the container pointer to the first container in the containers list
Definition: BESDataHandlerInterface.h:139
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:60
BESRequestHandlerList::find_handler
virtual BESRequestHandler * find_handler(const std::string &handler_name)
find and return the specified request handler
Definition: BESRequestHandlerList.cc:91
BESRequestHandlerList::get_handler_names
virtual std::string get_handler_names()
Returns a comma separated string of request handlers registered with the server.
Definition: BESRequestHandlerList.cc:130