bes  Updated for version 3.20.5
NCRequestHandler.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of nc_handler, a data handler for the OPeNDAP data
4 // server.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This is free software; you can redistribute it and/or modify it under the
10 // terms of the GNU Lesser General Public License as published by the Free
11 // Software Foundation; either version 2.1 of the License, or (at your
12 // option) any later version.
13 //
14 // This software is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 // 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 OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 // NCRequestHandler.cc
26 
27 #include "config_nc.h"
28 
29 #include <string>
30 #include <sstream>
31 #include <exception>
32 
33 #include <DMR.h>
34 #include <DataDDS.h>
35 #include <mime_util.h>
36 #include <D4BaseTypeFactory.h>
37 
38 #include <BESResponseHandler.h>
39 #include <BESResponseNames.h>
40 #include <BESDapNames.h>
41 #include <BESDASResponse.h>
42 #include <BESDDSResponse.h>
43 #include <BESDataDDSResponse.h>
44 #include <BESVersionInfo.h>
45 
46 #include <BESDapError.h>
47 #include <BESInternalFatalError.h>
48 #include <BESDataNames.h>
49 #include <TheBESKeys.h>
50 #include <BESServiceRegistry.h>
51 #include <BESUtil.h>
52 #include <BESDebug.h>
53 #include <BESStopWatch.h>
54 #include <BESContextManager.h>
55 #include <BESDMRResponse.h>
56 
57 #include <ObjMemCache.h>
58 
59 #include <InternalErr.h>
60 #include <Ancillary.h>
61 
62 #include "NCRequestHandler.h"
63 
64 #define NC_NAME "nc"
65 
66 using namespace libdap;
67 
68 bool NCRequestHandler::_show_shared_dims = true;
69 bool NCRequestHandler::_show_shared_dims_set = false;
70 
71 bool NCRequestHandler::_ignore_unknown_types = false;
72 bool NCRequestHandler::_ignore_unknown_types_set = false;
73 
74 bool NCRequestHandler::_promote_byte_to_short = false;
75 bool NCRequestHandler::_promote_byte_to_short_set = false;
76 
77 unsigned int NCRequestHandler::_cache_entries = 100;
78 float NCRequestHandler::_cache_purge_level = 0.2;
79 
80 ObjMemCache *NCRequestHandler::das_cache = 0;
81 ObjMemCache *NCRequestHandler::dds_cache = 0;
82 ObjMemCache *NCRequestHandler::dmr_cache = 0;
83 
84 extern void nc_read_dataset_attributes(DAS & das, const string & filename);
85 extern void nc_read_dataset_variables(DDS & dds, const string & filename);
86 
93 static bool version_ge(const string &version, float value)
94 {
95  try {
96  float v;
97  istringstream iss(version);
98  iss >> v;
99  //cerr << "version: " << v << ", value: " << value << endl;
100  return (v >= value);
101  }
102  catch (...) {
103  return false;
104  }
105 
106  return false; // quiet warnings...
107 }
108 
112 static bool get_bool_key(const string &key, bool def_val)
113 {
114  bool found = false;
115  string doset = "";
116  const string dosettrue = "true";
117  const string dosetyes = "yes";
118 
119  TheBESKeys::TheKeys()->get_value(key, doset, found);
120  if (true == found) {
121  doset = BESUtil::lowercase(doset);
122  return (dosettrue == doset || dosetyes == doset);
123  }
124  return def_val;
125 }
126 
127 static unsigned int get_uint_key(const string &key, unsigned int def_val)
128 {
129  bool found = false;
130  string doset = "";
131 
132  TheBESKeys::TheKeys()->get_value(key, doset, found);
133  if (true == found) {
134  return atoi(doset.c_str()); // use better code TODO
135  }
136  else {
137  return def_val;
138  }
139 }
140 
141 static float get_float_key(const string &key, float def_val)
142 {
143  bool found = false;
144  string doset = "";
145 
146  TheBESKeys::TheKeys()->get_value(key, doset, found);
147  if (true == found) {
148  return atof(doset.c_str()); // use better code TODO
149  }
150  else {
151  return def_val;
152  }
153 }
154 
155 NCRequestHandler::NCRequestHandler(const string &name) :
156  BESRequestHandler(name)
157 {
158  BESDEBUG(NC_NAME, "In NCRequestHandler::NCRequestHandler" << endl);
159 
160  add_method(DAS_RESPONSE, NCRequestHandler::nc_build_das);
161  add_method(DDS_RESPONSE, NCRequestHandler::nc_build_dds);
162  add_method(DATA_RESPONSE, NCRequestHandler::nc_build_data);
163 
164  add_method(DMR_RESPONSE, NCRequestHandler::nc_build_dmr);
165  add_method(DAP4DATA_RESPONSE, NCRequestHandler::nc_build_dmr);
166 
167  add_method(HELP_RESPONSE, NCRequestHandler::nc_build_help);
168  add_method(VERS_RESPONSE, NCRequestHandler::nc_build_version);
169 
170  // TODO replace with get_bool_key above 5/21/16 jhrg
171 
172  // Look for the SHowSharedDims property, if it has not been set
173  if (NCRequestHandler::_show_shared_dims_set == false) {
174  bool key_found = false;
175  string doset;
176  TheBESKeys::TheKeys()->get_value("NC.ShowSharedDimensions", doset, key_found);
177  if (key_found) {
178  // It was set in the conf file
179  NCRequestHandler::_show_shared_dims_set = true;
180 
181  doset = BESUtil::lowercase(doset);
182  if (doset == "true" || doset == "yes") {
183  NCRequestHandler::_show_shared_dims = true;
184  }
185  else
186  NCRequestHandler::_show_shared_dims = false;
187  }
188  }
189 
190  if (NCRequestHandler::_ignore_unknown_types_set == false) {
191  bool key_found = false;
192  string doset;
193  TheBESKeys::TheKeys()->get_value("NC.IgnoreUnknownTypes", doset, key_found);
194  if (key_found) {
195  doset = BESUtil::lowercase(doset);
196  if (doset == "true" || doset == "yes")
197  NCRequestHandler::_ignore_unknown_types = true;
198  else
199  NCRequestHandler::_ignore_unknown_types = false;
200 
201  NCRequestHandler::_ignore_unknown_types_set = true;
202  }
203  }
204 
205  if (NCRequestHandler::_promote_byte_to_short_set == false) {
206  bool key_found = false;
207  string doset;
208  TheBESKeys::TheKeys()->get_value("NC.PromoteByteToShort", doset, key_found);
209  if (key_found) {
210  doset = BESUtil::lowercase(doset);
211  if (doset == "true" || doset == "yes")
212  NCRequestHandler::_promote_byte_to_short = true;
213  else
214  NCRequestHandler::_promote_byte_to_short = false;
215 
216  NCRequestHandler::_promote_byte_to_short_set = true;
217  }
218  }
219 
220  NCRequestHandler::_cache_entries = get_uint_key("NC.CacheEntries", 0);
221  NCRequestHandler::_cache_purge_level = get_float_key("NC.CachePurgeLevel", 0.2);
222 
223  if (get_cache_entries()) { // else it stays at its default of null
224  das_cache = new ObjMemCache(get_cache_entries(), get_cache_purge_level());
225  dds_cache = new ObjMemCache(get_cache_entries(), get_cache_purge_level());
226  dmr_cache = new ObjMemCache(get_cache_entries(), get_cache_purge_level());
227  }
228 
229  BESDEBUG(NC_NAME, "Exiting NCRequestHandler::NCRequestHandler" << endl);
230 }
231 
232 NCRequestHandler::~NCRequestHandler()
233 {
234  delete das_cache;
235  delete dds_cache;
236  delete dmr_cache;
237 }
238 
239 bool NCRequestHandler::nc_build_das(BESDataHandlerInterface & dhi)
240 {
241  BESStopWatch sw;
242  if (BESISDEBUG( TIMING_LOG ))
243  sw.start("NCRequestHandler::nc_build_das", dhi.data[REQUEST_ID]);
244 
245  BESDEBUG(NC_NAME, "In NCRequestHandler::nc_build_das" << endl);
246 
247  BESResponseObject *response = dhi.response_handler->get_response_object();
248  BESDASResponse *bdas = dynamic_cast<BESDASResponse *> (response);
249  if (!bdas)
250  throw BESInternalError("cast error", __FILE__, __LINE__);
251 
252  try {
253  string container_name = bdas->get_explicit_containers() ? dhi.container->get_symbolic_name(): "";
254 
255  DAS *das = bdas->get_das();
256  if (!container_name.empty()) das->container_name(container_name);
257  string accessed = dhi.container->access();
258 
259  // Look in memory cache if it's initialized
260  DAS *cached_das_ptr = 0;
261  if (das_cache && (cached_das_ptr = static_cast<DAS*>(das_cache->get(accessed)))) {
262  // copy the cached DAS into the BES response object
263  BESDEBUG(NC_NAME, "DAS Cached hit for : " << accessed << endl);
264  *das = *cached_das_ptr;
265  }
266  else {
267  nc_read_dataset_attributes(*das, accessed);
268  Ancillary::read_ancillary_das(*das, accessed);
269  if (das_cache) {
270  // add a copy
271  BESDEBUG(NC_NAME, "DAS added to the cache for : " << accessed << endl);
272  das_cache->add(new DAS(*das), accessed);
273  }
274  }
275 
276  bdas->clear_container();
277  }
278  catch (BESError &e) {
279  throw;
280  }
281  catch (InternalErr & e) {
282  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
283  throw ex;
284  }
285  catch (Error & e) {
286  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
287  throw ex;
288  }
289  catch (std::exception &e) {
290  string s = string("C++ Exception: ") + e.what();
291  BESInternalFatalError ex(s, __FILE__, __LINE__);
292  throw ex;
293  }
294  catch (...) {
295  string s = "unknown exception caught building DAS";
296  BESInternalFatalError ex(s, __FILE__, __LINE__);
297  throw ex;
298  }
299 
300  BESDEBUG(NC_NAME, "Exiting NCRequestHandler::nc_build_das" << endl);
301  return true;
302 }
303 
310 void NCRequestHandler::get_dds_with_attributes(const string& dataset_name, const string& container_name, DDS* dds)
311 {
312  // Look in memory cache if it's initialized
313  DDS* cached_dds_ptr = 0;
314  if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->get(dataset_name)))) {
315  // copy the cached DDS into the BES response object. Assume that any cached DDS
316  // includes the DAS information.
317  BESDEBUG(NC_NAME, "DDS Cached hit for : " << dataset_name << endl);
318  *dds = *cached_dds_ptr; // Copy the referenced object
319  }
320  else {
321  if (!container_name.empty()) dds->container_name(container_name);
322  dds->filename(dataset_name);
323 
324  nc_read_dataset_variables(*dds, dataset_name);
325 
326  DAS* das = 0;
327  if (das_cache && (das = static_cast<DAS*>(das_cache->get(dataset_name)))) {
328  BESDEBUG(NC_NAME, "DAS Cached hit for : " << dataset_name << endl);
329  dds->transfer_attributes(das); // no need to cop the cached DAS
330  }
331  else {
332  das = new DAS;
333  // This looks at the 'use explicit containers' prop, and if true
334  // sets the current container for the DAS.
335  if (!container_name.empty()) das->container_name(container_name);
336 
337  nc_read_dataset_attributes(*das, dataset_name);
338  Ancillary::read_ancillary_das(*das, dataset_name);
339 
340  dds->transfer_attributes(das);
341 
342  // Only free the DAS if it's not added to the cache
343  if (das_cache) {
344  // add a copy
345  BESDEBUG(NC_NAME, "DAS added to the cache for : " << dataset_name << endl);
346  das_cache->add(das, dataset_name);
347  }
348  else {
349  delete das;
350  }
351  }
352 
353  if (dds_cache) {
354  // add a copy
355  BESDEBUG(NC_NAME, "DDS added to the cache for : " << dataset_name << endl);
356  dds_cache->add(new DDS(*dds), dataset_name);
357  }
358  }
359 }
360 
361 bool NCRequestHandler::nc_build_dds(BESDataHandlerInterface & dhi)
362 {
363 
364  BESStopWatch sw;
365  if (BESISDEBUG( TIMING_LOG ))
366  sw.start("NCRequestHandler::nc_build_dds", dhi.data[REQUEST_ID]);
367 
368  BESResponseObject *response = dhi.response_handler->get_response_object();
369  BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *> (response);
370  if (!bdds)
371  throw BESInternalError("cast error", __FILE__, __LINE__);
372 
373  try {
374  // If there's no value for this set in the conf file, look at the context
375  // and set the default behavior based on the protocol version clients say
376  // they will accept.
377  if (NCRequestHandler::_show_shared_dims_set == false) {
378  bool context_found = false;
379  string context_value = BESContextManager::TheManager()->get_context("xdap_accept", context_found);
380  if (context_found) {
381  BESDEBUG(NC_NAME, "xdap_accept: " << context_value << endl);
382  if (version_ge(context_value, 3.2))
383  NCRequestHandler::_show_shared_dims = false;
384  else
385  NCRequestHandler::_show_shared_dims = true;
386  }
387  }
388 
389  string container_name = bdds->get_explicit_containers() ? dhi.container->get_symbolic_name(): "";
390  DDS *dds = bdds->get_dds();
391 
392  // Build a DDS in the empty DDS object
393  get_dds_with_attributes(dhi.container->access(), container_name, dds);
394 
395  bdds->set_constraint(dhi);
396  bdds->clear_container();
397  }
398  catch (BESError &e) {
399  throw e;
400  }
401  catch (InternalErr & e) {
402  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
403  throw ex;
404  }
405  catch (Error & e) {
406  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
407  throw ex;
408  }
409  catch (std::exception &e) {
410  string s = string("C++ Exception: ") + e.what();
411  BESInternalFatalError ex(s, __FILE__, __LINE__);
412  throw ex;
413  }
414  catch (...) {
415  string s = "unknown exception caught building DDS";
416  BESInternalFatalError ex(s, __FILE__, __LINE__);
417  throw ex;
418  }
419 
420  return true;
421 }
422 
423 bool NCRequestHandler::nc_build_data(BESDataHandlerInterface & dhi)
424 {
425  BESStopWatch sw;
426  if (BESISDEBUG( TIMING_LOG ))
427  sw.start("NCRequestHandler::nc_build_data", dhi.data[REQUEST_ID]);
428 
429  BESResponseObject *response = dhi.response_handler->get_response_object();
430  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *> (response);
431  if (!bdds)
432  throw BESInternalError("cast error", __FILE__, __LINE__);
433 
434  try {
435  if (NCRequestHandler::_show_shared_dims_set == false) {
436  bool context_found = false;
437  string context_value = BESContextManager::TheManager()->get_context("xdap_accept", context_found);
438  if (context_found) {
439  BESDEBUG(NC_NAME, "xdap_accept: " << context_value << endl);
440  if (version_ge(context_value, 3.2))
441  NCRequestHandler::_show_shared_dims = false;
442  else
443  NCRequestHandler::_show_shared_dims = true;
444  }
445  }
446 
447  string container_name = bdds->get_explicit_containers() ? dhi.container->get_symbolic_name(): "";
448  DDS *dds = bdds->get_dds();
449 
450  // Build a DDS in the empty DDS object
451  get_dds_with_attributes(dhi.container->access(), container_name, dds);
452 
453  bdds->set_constraint(dhi);
454  bdds->clear_container();
455  }
456  catch (BESError &e) {
457  throw;
458  }
459  catch (InternalErr & e) {
460  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
461  throw ex;
462  }
463  catch (Error & e) {
464  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
465  throw ex;
466  }
467  catch (std::exception &e) {
468  string s = string("C++ Exception: ") + e.what();
469  BESInternalFatalError ex(s, __FILE__, __LINE__);
470  throw ex;
471  }
472  catch (...) {
473  string s = "unknown exception caught building DAS";
474  BESInternalFatalError ex(s, __FILE__, __LINE__);
475  throw ex;
476  }
477 
478  return true;
479 }
480 
481 bool NCRequestHandler::nc_build_dmr(BESDataHandlerInterface &dhi)
482 {
483  BESStopWatch sw;
484  if (BESISDEBUG( TIMING_LOG ))
485  sw.start("NCRequestHandler::nc_build_dmr", dhi.data[REQUEST_ID]);
486 
487  // Extract the DMR Response object - this holds the DMR used by the
488  // other parts of the framework.
489  BESResponseObject *response = dhi.response_handler->get_response_object();
490  BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);
491 
492  // Because this code does not yet know how to build a DMR directly, use
493  // the DMR ctor that builds a DMR using a 'full DDS' (a DDS with attributes).
494  // First step, build the 'full DDS'
495  string dataset_name = dhi.container->access();
496 
497  // Get the DMR made by the BES in the BES/dap/BESDMRResponseHandler, make sure there's a
498  // factory we can use and then dump the DAP2 variables and attributes in using the
499  // BaseType::transform_to_dap4() method that transforms individual variables
500  DMR *dmr = bdmr.get_dmr();
501 
502  try {
503  DMR* cached_dmr_ptr = 0;
504  if (dmr_cache && (cached_dmr_ptr = static_cast<DMR*>(dmr_cache->get(dataset_name)))) {
505  // copy the cached DMR into the BES response object
506  BESDEBUG(NC_NAME, "DMR Cached hit for : " << dataset_name << endl);
507  *dmr = *cached_dmr_ptr; // Copy the referenced object
508  }
509  else {
510 #if 0
511  // this version builds and caches the DDS/DAS info.
512  BaseTypeFactory factory;
513  DDS dds(&factory, name_path(dataset_name), "3.2");
514 
515  // This will get the DDS, either by building it or from the cache
516  get_dds_with_attributes(dataset_name, "", &dds);
517 
518  dmr->set_factory(new D4BaseTypeFactory);
519  dmr->build_using_dds(dds);
520 #else
521  // This version builds a DDS only to build the resulting DMR. The DDS is
522  // not cached. It does look in the DDS cache, just in case...
523  dmr->set_factory(new D4BaseTypeFactory);
524 
525  DDS *dds_ptr = 0;
526  if (dds_cache && (dds_ptr = static_cast<DDS*>(dds_cache->get(dataset_name)))) {
527  // Use the cached DDS; Assume that all cached DDS objects hold DAS info too
528  BESDEBUG(NC_NAME, "DDS Cached hit (while building DMR) for : " << dataset_name << endl);
529 
530  dmr->build_using_dds(*dds_ptr);
531  }
532  else {
533  // Build a throw-away DDS; don't bother to cache it. DMR's don't support
534  // containers.
535  BaseTypeFactory factory;
536  DDS dds(&factory, name_path(dataset_name), "3.2");
537 
538  dds.filename(dataset_name);
539  nc_read_dataset_variables(dds, dataset_name);
540 
541  DAS das;
542 
543  nc_read_dataset_attributes(das, dataset_name);
544  Ancillary::read_ancillary_das(das, dataset_name);
545 
546  dds.transfer_attributes(&das);
547  dmr->build_using_dds(dds);
548  }
549 #endif
550 
551  if (dmr_cache) {
552  // add a copy
553  BESDEBUG(NC_NAME, "DMR added to the cache for : " << dataset_name << endl);
554  dmr_cache->add(new DMR(*dmr), dataset_name);
555  }
556  }
557 
558  // Instead of fiddling with the internal storage of the DHI object,
559  // (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
560  // methods to set the constraints. But, why? Ans: from Patrick is that
561  // in the 'container' mode of BES each container can have a different
562  // CE.
563  bdmr.set_dap4_constraint(dhi);
564  bdmr.set_dap4_function(dhi);
565  }
566  catch (InternalErr &e) {
567  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
568  }
569  catch (Error &e) {
570  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
571  }
572  catch (...) {
573  throw BESDapError("Caught unknown error build NC DMR response", true, unknown_error, __FILE__, __LINE__);
574  }
575 
576  return true;
577 }
578 
579 bool NCRequestHandler::nc_build_help(BESDataHandlerInterface & dhi)
580 {
581  BESStopWatch sw;
582  if (BESISDEBUG( TIMING_LOG ))
583  sw.start("NCRequestHandler::nc_build_help", dhi.data[REQUEST_ID]);
584 
585  BESResponseObject *response = dhi.response_handler->get_response_object();
586  BESInfo *info = dynamic_cast<BESInfo *> (response);
587  if (!info)
588  throw BESInternalError("cast error", __FILE__, __LINE__);
589 
590  map < string, string > attrs;
591  attrs["name"] = MODULE_NAME ;
592  attrs["version"] = MODULE_VERSION ;
593 #if 0
594  attrs["name"] = PACKAGE_NAME;
595  attrs["version"] = PACKAGE_VERSION;
596 #endif
597  list < string > services;
598  BESServiceRegistry::TheRegistry()->services_handled(NC_NAME, services);
599  if (services.size() > 0) {
600  string handles = BESUtil::implode(services, ',');
601  attrs["handles"] = handles;
602  }
603  info->begin_tag("module", &attrs);
604  info->end_tag("module");
605 
606  return true;
607 }
608 
609 bool NCRequestHandler::nc_build_version(BESDataHandlerInterface & dhi)
610 {
611  BESStopWatch sw;
612  if (BESISDEBUG( TIMING_LOG ))
613  sw.start("NCRequestHandler::nc_build_version", dhi.data[REQUEST_ID]);
614 
615  BESResponseObject *response = dhi.response_handler->get_response_object();
616  BESVersionInfo *info = dynamic_cast<BESVersionInfo *> (response);
617  if (!info)
618  throw BESInternalError("cast error", __FILE__, __LINE__);
619 
620 #if 0
621  info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
622 #endif
623  info->add_module(MODULE_NAME, MODULE_VERSION);
624 
625  return true;
626 }
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
BESDapResponse::set_dap4_constraint
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:133
BESInternalFatalError
exception thrown if an internal error is found and is fatal to the BES
Definition: BESInternalFatalError.h:43
BESContainer::get_symbolic_name
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:224
ObjMemCache
An in-memory cache for DapObj (DAS, DDS, ...) objects.
Definition: ObjMemCache.h:86
BESContainer::access
virtual string access()=0
returns the true name of this container
BESDapResponse::set_dap4_function
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:150
BESContextManager::get_context
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
Definition: BESContextManager.cc:73
BESDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDDSResponse.cc:73
BESDDSResponse::get_dds
libdap::DDS * get_dds()
Definition: BESDDSResponse.h:80
BESDASResponse
Represents an OPeNDAP DAS DAP2 data object within the BES.
Definition: BESDASResponse.h:46
BESInfo
informational response object
Definition: BESInfo.h:68
ObjMemCache::add
virtual void add(libdap::DapObj *obj, const std::string &key)
Add an object to the cache and associate it with a key.
Definition: ObjMemCache.cc:63
libdap
Definition: BESDapFunctionResponseCache.h:35
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
BESResponseHandler::get_response_object
virtual BESResponseObject * get_response_object()
return the current response object
Definition: BESResponseHandler.cc:78
BESVersionInfo
Definition: BESVersionInfo.h:47
BESStopWatch::start
virtual bool start(string name)
Definition: BESStopWatch.cc:57
BESUtil::lowercase
static string lowercase(const string &s)
Definition: BESUtil.cc:197
BESDapResponse::get_explicit_containers
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
Definition: BESDapResponse.h:70
BESDataDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDataDDSResponse.cc:59
BESInternalError
exception thrown if inernal error encountered
Definition: BESInternalError.h:43
BESStopWatch
Definition: BESStopWatch.h:55
TheBESKeys::get_value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:420
BESDDSResponse
Holds a DDS object within the BES.
Definition: BESDDSResponse.h:50
BESDASResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDASResponse.cc:58
BESDapResponse::set_constraint
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:111
BESDataDDSResponse
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Definition: BESDataDDSResponse.h:46
Error
BESDataHandlerInterface::data
map< string, string > data
the map of string data that will be required for the current request.
Definition: BESDataHandlerInterface.h:94
BESDapError
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:60
BESServiceRegistry::services_handled
virtual void services_handled(const string &handler, list< string > &services)
returns the list of servies provided by the handler in question
Definition: BESServiceRegistry.cc:328
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
BESUtil::implode
static string implode(const list< string > &values, char delim)
Definition: BESUtil.cc:635
BESResponseObject
Abstract base class representing a specific set of information in response to a request to the BES.
Definition: BESResponseObject.h:51
ObjMemCache::get
virtual libdap::DapObj * get(const std::string &key)
Get the cached pointer.
Definition: ObjMemCache.cc:105
BESDMRResponse
Represents an OPeNDAP DMR DAP4 data object within the BES.
Definition: BESDMRResponse.h:39