bes  Updated for version 3.20.6
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 using std::endl;
40 using std::ostream;
41 using std::string;
42 
43 BESRequestHandlerList *BESRequestHandlerList::_instance = 0;
44 
54 bool BESRequestHandlerList::add_handler(const string &handler_name, BESRequestHandler *handler_object)
55 {
56  if (find_handler(handler_name) == 0) {
57  _handler_list[handler_name] = handler_object;
58  return true;
59  }
60  return false;
61 }
62 
76 BESRequestHandlerList::remove_handler(const string &handler_name)
77 {
78  BESRequestHandler *ret = 0;
79  BESRequestHandlerList::Handler_iter i;
80  i = _handler_list.find(handler_name);
81  if (i != _handler_list.end()) {
82  ret = (*i).second;
83  _handler_list.erase(i);
84  }
85  return ret;
86 }
87 
95 BESRequestHandlerList::find_handler(const string &handler_name)
96 {
97  BESRequestHandlerList::Handler_citer i;
98  i = _handler_list.find(handler_name);
99  if (i != _handler_list.end()) {
100  return (*i).second;
101  }
102  return 0;
103 }
104 
112 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_first_handler()
113 {
114  return _handler_list.begin();
115 }
116 
122 BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_last_handler()
123 {
124  return _handler_list.end();
125 }
126 
135 {
136  string ret = "";
137  bool first_name = true;
138  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
139  for (; i != _handler_list.end(); i++) {
140  if (!first_name) ret += ", ";
141  ret += (*i).first;
142  first_name = false;
143  }
144  return ret;
145 }
146 
168 {
169  dhi.first_container();
170  while (dhi.container) {
171  execute_current(dhi);
172  dhi.next_container();
173  }
174 }
175 
195 {
196  BESRequestHandlerList::Handler_citer i = get_first_handler();
197  BESRequestHandlerList::Handler_citer ie = get_last_handler();
198  for (; i != ie; i++) {
199  BESRequestHandler *rh = (*i).second;
200  p_request_handler_method p = rh->find_method(dhi.action);
201  if (p) {
202  p(dhi);
203  }
204  }
205 }
206 
207 #if 0
208 
228 void BESRequestHandlerList::execute_once(BESDataHandlerInterface &dhi)
229 {
230  dhi.first_container();
231  execute_current(dhi);
232 }
233 #endif
234 
252 {
253  if (dhi.container) {
254  // Patrick's comment: This needs to happen here, but really should be done
255  // in the get_container_type method in the container class if it
256  // needs to happen.
257  //
258  // This call will, for BESFileContainer, decompress and cache compressed files,
259  // changing their extensions from, e.g., '.gz' to '.h5' and enabling the
260  // get_container_type() method to function correctly. jhrg 5/31/18
261  dhi.container->access();
262 
263  // Given the kind of thing in the DHI's container (netcdf file, ...) find the
264  // RequestHandler that understands that and then find the method in that handler
265  // that can process the DHI's action.
267  if (!rh)
268  throw BESInternalError(string("The data handler '") + dhi.container->get_container_type() + "' does not exist",
269  __FILE__, __LINE__);
270 
271  p_request_handler_method request_handler_method = rh->find_method(dhi.action);
272  if (!request_handler_method) {
273  throw BESInternalError(string("Request handler for '") + dhi.container->get_container_type()
274  + "' does not handle the response type '" + dhi.action + "'", __FILE__, __LINE__);
275  }
276 
277  request_handler_method(dhi); // This is where the request handler method is called
278  }
279 }
280 
288 void BESRequestHandlerList::dump(ostream &strm) const
289 {
290  strm << BESIndent::LMarg << "BESRequestHandlerList::dump - (" << (void *) this << ")" << endl;
291  BESIndent::Indent();
292  if (_handler_list.size()) {
293  strm << BESIndent::LMarg << "registered handlers:" << endl;
294  BESIndent::Indent();
295  BESRequestHandlerList::Handler_citer i = _handler_list.begin();
296  BESRequestHandlerList::Handler_citer ie = _handler_list.end();
297  for (; i != ie; i++) {
298  BESRequestHandler *rh = (*i).second;
299  rh->dump(strm);
300  }
301  BESIndent::UnIndent();
302  }
303  else {
304  strm << BESIndent::LMarg << "registered handlers: none" << endl;
305  }
306  BESIndent::UnIndent();
307 }
308 
310 BESRequestHandlerList::TheList()
311 {
312  if (_instance == 0) {
313  _instance = new BESRequestHandlerList;
314  }
315  return _instance;
316 }
317 
BESRequestHandler
Represents a specific data type request handler.
Definition: BESRequestHandler.h:74
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:75
BESRequestHandlerList::remove_handler
virtual BESRequestHandler * remove_handler(const std::string &handler_name)
remove and return the specified request handler
Definition: BESRequestHandlerList.cc:76
BESRequestHandler::find_method
virtual p_request_handler_method find_method(const std::string &name)
find the method that can handle the specified response object type
Definition: BESRequestHandler.cc:95
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:251
BESRequestHandlerList::execute_all
virtual void execute_all(BESDataHandlerInterface &dhi)
for all of the registered request handlers, execute the given request
Definition: BESRequestHandlerList.cc:194
BESDataHandlerInterface::action
std::string action
the response object requested, e.g. das, dds
Definition: BESDataHandlerInterface.h:79
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:146
BESRequestHandlerList
The list of registered request handlers for this server; a singleton.
Definition: BESRequestHandlerList.h:70
BESContainer::get_container_type
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
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:167
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:54
BESContainer::access
virtual std::string access()=0
returns the true name of this container
BESRequestHandlerList::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESRequestHandlerList.cc:288
BESInternalError
exception thrown if internal 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:122
BESRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESRequestHandler.cc:163
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:112
BESDataHandlerInterface::first_container
void first_container()
set the container pointer to the first container in the containers list
Definition: BESDataHandlerInterface.h:135
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
BESRequestHandlerList::find_handler
virtual BESRequestHandler * find_handler(const std::string &handler_name)
find and return the specified request handler
Definition: BESRequestHandlerList.cc:95
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:134