27 #include "DapRequestHandler.h" 29 #include <BESResponseHandler.h> 30 #include <BESResponseNames.h> 31 #include <BESVersionInfo.h> 32 #include <BESTextInfo.h> 33 #include <BESDapNames.h> 35 #include <BESDataDDSResponse.h> 36 #include <BESDDSResponse.h> 37 #include <BESDASResponse.h> 38 #include <BESDMRResponse.h> 40 #include <BESConstraintFuncs.h> 41 #include <BESServiceRegistry.h> 43 #include <TheBESKeys.h> 45 #include <BESDapError.h> 46 #include <BESInternalFatalError.h> 49 #include <BaseTypeFactory.h> 50 #include <test/TestTypeFactory.h> 51 #include <D4BaseTypeFactory.h> 52 #include <test/D4TestTypeFactory.h> 53 #include <test/TestCommon.h> 57 #include <D4Connect.h> 58 #include <D4ParserSax2.h> 60 #include <Ancillary.h> 63 #include <InternalErr.h> 64 #include <mime_util.h> 68 int test_variable_sleep_interval = 0;
70 bool DapRequestHandler::d_use_series_values =
true;
71 bool DapRequestHandler::d_use_series_values_set =
false;
73 bool DapRequestHandler::d_use_test_types =
true;
74 bool DapRequestHandler::d_use_test_types_set =
false;
76 const string module =
"dapreader";
78 static void read_key_value(
const std::string &key_name,
bool &key_value,
bool &is_key_set)
80 if (is_key_set ==
false) {
81 bool key_found =
false;
89 key_value = (doset ==
"true" || doset ==
"yes");
94 static bool extension_match(
const string &data_source,
const string &extension)
96 string::size_type pos = data_source.rfind(extension);
97 return pos != string::npos && pos + extension.length() == data_source.length();
100 DapRequestHandler::DapRequestHandler(
const string &name) :
103 add_method(DAS_RESPONSE, dap_build_das);
104 add_method(DDS_RESPONSE, dap_build_dds);
105 add_method(DATA_RESPONSE, dap_build_data);
107 add_method(DMR_RESPONSE, dap_build_dmr);
108 add_method(DAP4DATA_RESPONSE, dap_build_dap4data);
110 add_method(VERS_RESPONSE, dap_build_vers);
111 add_method(HELP_RESPONSE, dap_build_help);
113 read_key_value(
"DR.UseTestTypes", d_use_test_types, d_use_test_types_set);
114 read_key_value(
"DR.UseSeriesValues", d_use_series_values, d_use_series_values_set);
123 void DapRequestHandler::load_dds_from_data_file(
const string &accessed, DDS &dds)
125 BESDEBUG(
"dapreader",
"In DapRequestHandler::load_dds_from_data_file; accessed: " << accessed << endl);
127 if (d_use_test_types)
128 dds.set_factory(
new TestTypeFactory);
130 dds.set_factory(
new BaseTypeFactory);
132 auto_ptr<Connect> url(
new Connect(accessed));
133 Response r(fopen(accessed.c_str(),
"r"), 0);
134 if (!r.get_stream())
throw Error(
string(
"The input source: ") + accessed + string(
" could not be opened"));
135 url->read_data_no_mime(dds, &r);
137 auto_ptr<DAS> das(
new DAS);
138 Ancillary::read_ancillary_das(*das, accessed);
140 if (das->get_size() > 0) dds.transfer_attributes(das.get());
145 for (DDS::Vars_iter i = dds.var_begin(), e = dds.var_end(); i != e; i++) {
146 (*i)->set_read_p(
true);
157 void DapRequestHandler::build_dds_from_file(
const string &accessed,
bool explicit_containers, DDS *dds)
159 BESDEBUG(
"dapreader",
"In DapRequestHandler::build_dds_from_file; accessed: " << accessed << endl);
161 if (extension_match(accessed,
".dds") && d_use_test_types) {
162 dds->set_factory(
new TestTypeFactory);
163 dds->parse(accessed);
166 Ancillary::read_ancillary_das(*das, accessed);
168 if (das->get_size() > 0) dds->transfer_attributes(das);
170 else if (extension_match(accessed,
".dods") || extension_match(accessed,
".data")) {
171 if (explicit_containers) {
172 BESDEBUG(
"dapreader",
"In DapRequestHandler::build_dds_from_file; in container code" << endl);
181 load_dds_from_data_file(accessed, local_dds);
184 for (DDS::Vars_iter i = local_dds.var_begin(), e = local_dds.var_end(); i != e; i++) {
188 dds->set_dataset_name(name_path(accessed));
191 BESDEBUG(
"dapreader",
"In DapRequestHandler::build_dds_from_file; in plain code" << endl);
193 load_dds_from_data_file(accessed, *dds);
196 dds->filename(accessed);
199 throw Error(
"The dapreader module can only return DDS/DODS responses for files ending in .dods, .data or .dds");
202 BESDEBUG(
"dapreader2",
"DDS/DDX in DapRequestHandler::build_dds_from_file: ");
206 void DapRequestHandler::build_dmr_from_file(
const string& accessed,
bool explicit_containers, DMR* dmr)
208 BESDEBUG(
"dapreader",
"In DapRequestHandler::build_dmr_from_file; accessed: " << accessed << endl);
210 dmr->set_filename(accessed);
211 dmr->set_name(name_path(accessed));
213 D4TestTypeFactory TestFactory;
214 D4BaseTypeFactory BaseFactory;
215 if (d_use_test_types) {
216 dmr->set_factory(&TestFactory);
219 dmr->set_factory(&BaseFactory);
222 if ((extension_match(accessed,
".dmr") || extension_match(accessed,
".xml")) && d_use_test_types) {
224 ifstream in(accessed.c_str(), ios::in);
225 parser.intern(in, dmr);
227 else if (extension_match(accessed,
".dap")) {
228 auto_ptr<D4Connect> url(
new D4Connect(accessed));
229 fstream f(accessed.c_str(), std::ios_base::in);
230 if (!f.is_open() || f.bad() || f.eof())
throw Error((
string) (
"Could not open: ") + accessed);
235 url->read_data_no_mime(*dmr, r);
237 else if (extension_match(accessed,
".dds") || extension_match(accessed,
".dods")
238 || extension_match(accessed,
".data")) {
240 auto_ptr<DDS> dds(
new DDS(0 ));
242 build_dds_from_file(accessed, explicit_containers, dds.get());
244 dmr->build_using_dds(*dds);
248 throw Error(
"The dapreader module can only return DMR/DAP responses for files ending in .dmr, .xml or .dap");
267 BESDEBUG(module,
"Entering dap_build_dmr..." << endl);
271 if (!bdmr)
throw BESInternalError(
"BESDMRResponse cast error", __FILE__, __LINE__);
282 catch (InternalErr & e) {
283 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
286 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
292 BESDEBUG(module,
"Leaving dap_build_dmr..." << endl);
305 BESDEBUG(module,
"Entering dap_build_dap4data..." << endl);
309 if (!bdmr)
throw BESInternalError(
"BESDMRResponse cast error", __FILE__, __LINE__);
312 DMR *dmr = bdmr->get_dmr();
315 if (d_use_series_values) {
316 dmr->root()->set_read_p(
false);
318 TestCommon *tc = dynamic_cast<TestCommon*>(dmr->root());
320 tc->set_series_values(
true);
322 throw Error(
"In the reader handler: Could not set UseSeriesValues");
331 catch (InternalErr & e) {
332 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
335 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
338 throw BESInternalFatalError(
"Unknown exception caught building DAP4 Data response", __FILE__, __LINE__);
341 BESDEBUG(module,
"Leaving dap_build_dap4data..." << endl);
360 DAS *das = bdas->get_das();
363 if (extension_match(accessed,
".das")) {
364 das->parse(accessed);
366 else if (extension_match(accessed,
".dods") || extension_match(accessed,
".data")) {
367 Ancillary::read_ancillary_das(*das, accessed);
371 "The dapreader module can only return DAS responses for files ending in .das or .dods/.data.\nIn the latter case there must be an ancillary das file present.");
379 catch (InternalErr & e) {
380 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
383 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
395 BESDEBUG(module,
"Entering dap_build_dds..." << endl);
412 catch (InternalErr & e) {
413 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
416 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
422 BESDEBUG(module,
"Exiting dap_build_dds..." << endl);
429 BESDEBUG(module,
"Entering dap_build_data..." << endl);
446 catch (InternalErr & e) {
447 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
450 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
453 throw BESInternalFatalError(
"Unknown exception caught building a data response", __FILE__, __LINE__);
456 BESDEBUG(module,
"Exiting dap_build_data..." << endl);
466 info->add_module(DAPREADER_PACKAGE, DAPREADER_VERSION);
477 map<string, string> attrs;
478 attrs[
"name"] = DAPREADER_PACKAGE ;
479 attrs[
"version"] = DAPREADER_VERSION ;
480 list<string> services;
482 if (services.size() > 0) {
484 attrs[
"handles"] = handles;
486 info->begin_tag(
"module", &attrs);
487 info->end_tag(
"module");
494 strm << BESIndent::LMarg <<
"DapRequestHandler::dump - (" << (
void *)
this <<
")" << endl;
497 BESIndent::UnIndent();
exception thrown if an internal error is found and is fatal to the BES
static std::ostream * GetStrm()
return the debug stream
exception thrown if inernal error encountered
static string lowercase(const string &s)
virtual void dump(ostream &strm) const
dumps information about this object
Holds a DDS object within the BES.
virtual void clear_container()
clear the container in the DAP response object
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static bool dap_build_dmr(BESDataHandlerInterface &dhi)
virtual void set_container(const std::string &cn)
set the container in the DAP response object
virtual string access()=0
returns the true name of this container
virtual void clear_container()
clear the container in the DAP response object
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
informational response object
static string implode(const list< string > &values, char delim)
virtual BESResponseObject * get_response_object()
return the current response object
Abstract exception class for the BES with basic string message.
static TheBESKeys * TheKeys()
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Represents an OPeNDAP DMR DAP4 data object within the BES.
error object created from libdap error objects and can handle those errors
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
virtual void clear_container()
clear the container in the DAP response object
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.
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
virtual void set_container(const string &cn)
set the container in the DAP response object
Represents an OPeNDAP DAS DAP2 data object within the BES.
static bool dap_build_das(BESDataHandlerInterface &dhi)
virtual void set_container(const string &cn)
set the container in the DAP response object
Abstract base class representing a specific set of information in response to a request to the BES.
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
BESContainer * container
pointer to current container in this interface
virtual void services_handled(const string &handler, list< string > &services)
returns the list of servies provided by the handler in question
string get_symbolic_name() const
retrieve the symbolic name for this container