bes Updated for version 3.20.10
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#include <mutex>
35
36#include "BESRequestHandlerList.h"
37#include "BESRequestHandler.h"
38#include "BESInternalError.h"
39
40using std::endl;
41using std::ostream;
42using std::string;
43
44BESRequestHandlerList *BESRequestHandlerList::d_instance = nullptr;
45static std::once_flag d_euc_init_once;
46
47BESRequestHandlerList::BESRequestHandlerList() {}
48
49BESRequestHandlerList::~BESRequestHandlerList() {}
50
60bool BESRequestHandlerList::add_handler(const string &handler_name, BESRequestHandler *handler_object)
61{
62 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
63
64 if (find_handler(handler_name) == 0) {
65 _handler_list[handler_name] = handler_object;
66 return true;
67 }
68 return false;
69}
70
84BESRequestHandlerList::remove_handler(const string &handler_name)
85{
86 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
87
88 BESRequestHandler *ret = 0;
89 BESRequestHandlerList::Handler_iter i;
90 i = _handler_list.find(handler_name);
91 if (i != _handler_list.end()) {
92 ret = (*i).second;
93 _handler_list.erase(i);
94 }
95 return ret;
96}
97
105BESRequestHandlerList::find_handler(const string &handler_name)
106{
107 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
108
109 BESRequestHandlerList::Handler_citer i;
110 i = _handler_list.find(handler_name);
111 if (i != _handler_list.end()) {
112 return (*i).second;
113 }
114 return 0;
115}
116
124BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_first_handler()
125{
126 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
127
128 return _handler_list.begin();
129}
130
136BESRequestHandlerList::Handler_citer BESRequestHandlerList::get_last_handler()
137{
138 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
139
140 return _handler_list.end();
141}
142
151{
152 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
153
154 string ret = "";
155 bool first_name = true;
156 BESRequestHandlerList::Handler_citer i = _handler_list.begin();
157 for (; i != _handler_list.end(); i++) {
158 if (!first_name) ret += ", ";
159 ret += (*i).first;
160 first_name = false;
161 }
162 return ret;
163}
164
186{
187 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
188
189 dhi.first_container();
190 while (dhi.container) {
191 execute_current(dhi);
192 dhi.next_container();
193 }
194}
195
215{
216 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
217
218 BESRequestHandlerList::Handler_citer i = get_first_handler();
219 BESRequestHandlerList::Handler_citer ie = get_last_handler();
220 for (; i != ie; i++) {
221 BESRequestHandler *rh = (*i).second;
222 p_request_handler_method p = rh->find_method(dhi.action);
223 if (p) {
224 p(dhi);
225 }
226 }
227}
228
229#if 0
250void BESRequestHandlerList::execute_once(BESDataHandlerInterface &dhi)
251{
252 dhi.first_container();
253 execute_current(dhi);
254}
255#endif
256
274{
275 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
276
277 if (dhi.container) {
278 // Patrick's comment: This needs to happen here, but really should be done
279 // in the get_container_type method in the container class if it
280 // needs to happen.
281 //
282 // This call will, for BESFileContainer, decompress and cache compressed files,
283 // changing their extensions from, e.g., '.gz' to '.h5' and enabling the
284 // get_container_type() method to function correctly. jhrg 5/31/18
285 dhi.container->access();
286
287 // Given the kind of thing in the DHI's container (netcdf file, ...) find the
288 // RequestHandler that understands that and then find the method in that handler
289 // that can process the DHI's action.
291 if (!rh)
292 throw BESInternalError(string("The data handler '") + dhi.container->get_container_type() + "' does not exist",
293 __FILE__, __LINE__);
294
295 p_request_handler_method request_handler_method = rh->find_method(dhi.action);
296 if (!request_handler_method) {
297 throw BESInternalError(string("Request handler for '") + dhi.container->get_container_type()
298 + "' does not handle the response type '" + dhi.action + "'", __FILE__, __LINE__);
299 }
300
301 request_handler_method(dhi); // This is where the request handler method is called
302 }
303}
304
312void BESRequestHandlerList::dump(ostream &strm) const
313{
314 std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
315
316 strm << BESIndent::LMarg << "BESRequestHandlerList::dump - (" << (void *) this << ")" << endl;
317 BESIndent::Indent();
318 if (_handler_list.size()) {
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 BESRequestHandler *rh = (*i).second;
325 rh->dump(strm);
326 }
327 BESIndent::UnIndent();
328 }
329 else {
330 strm << BESIndent::LMarg << "registered handlers: none" << endl;
331 }
332 BESIndent::UnIndent();
333}
334
336BESRequestHandlerList::TheList()
337{
338 std::call_once(d_euc_init_once,BESRequestHandlerList::initialize_instance);
339 return d_instance;
340}
341
342void BESRequestHandlerList::initialize_instance() {
343 d_instance = new BESRequestHandlerList;
344#ifdef HAVE_ATEXIT
345 atexit(delete_instance);
346#endif
347}
348
349void BESRequestHandlerList::delete_instance() {
350 delete d_instance;
351 d_instance = 0;
352}
353
354
355
virtual std::string access()=0
returns the true name of this container
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
Structure storing information used by the BES to handle the request.
std::string action
the response object requested, e.g. das, dds
void first_container()
set the container pointer to the first container in the containers list
BESContainer * container
pointer to current container in this interface
void next_container()
set the container pointer to the next * container in the list, null if at the end or no containers in...
exception thrown if internal error encountered
The list of registered request handlers for this server; a singleton.
virtual void execute_all(BESDataHandlerInterface &dhi)
for all of the registered request handlers, execute the given request
virtual std::string get_handler_names()
Returns a comma separated string of request handlers registered with the server.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual bool add_handler(const std::string &handler_name, BESRequestHandler *handler)
add a request handler to the list of registered handlers for this server
virtual BESRequestHandler * remove_handler(const std::string &handler_name)
remove and return the specified request handler
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...
virtual void execute_each(BESDataHandlerInterface &dhi)
for each container in the given data handler interface, execute the given request
virtual Handler_citer get_first_handler()
return an iterator pointing to the first request handler in the list
virtual BESRequestHandler * find_handler(const std::string &handler_name)
find and return the specified request handler
Represents a specific data type request handler.
virtual p_request_handler_method find_method(const std::string &name)
find the method that can handle the specified response object type
virtual void dump(std::ostream &strm) const
dumps information about this object