34#include <libdap/DMR.h>
35#include <libdap/DataDDS.h>
37#include <libdap/mime_util.h>
38#include <libdap/D4BaseTypeFactory.h>
40#include "NCMLRequestHandler.h"
42#include <BESConstraintFuncs.h>
43#include <BESContainerStorage.h>
44#include <BESContainerStorageList.h>
45#include <BESDapNames.h>
46#include "BESDataDDSResponse.h"
47#include <BESDataNames.h>
48#include <BESDASResponse.h>
49#include <BESDDSResponse.h>
50#include <BESDMRResponse.h>
53#include "BESStopWatch.h"
54#include <BESInternalError.h>
55#include <BESDapError.h>
57#include <BESRequestHandlerList.h>
58#include <BESResponseHandler.h>
59#include <BESResponseNames.h>
60#include <BESServiceRegistry.h>
61#include <BESTextInfo.h>
63#include <BESVersionInfo.h>
64#include <TheBESKeys.h>
70#include "NCMLParser.h"
71#include "NCMLResponseNames.h"
72#include "SimpleLocationParser.h"
79#define prolog std::string("NCMLRequestHandler::").append(__func__).append("() - ")
82bool NCMLRequestHandler::_global_attributes_container_name_set =
false;
83string NCMLRequestHandler::_global_attributes_container_name;
85NCMLRequestHandler::NCMLRequestHandler(
const string &name) :
88 add_method(DAS_RESPONSE, NCMLRequestHandler::ncml_build_das);
89 add_method(DDS_RESPONSE, NCMLRequestHandler::ncml_build_dds);
90 add_method(DATA_RESPONSE, NCMLRequestHandler::ncml_build_data);
92 add_method(DMR_RESPONSE, NCMLRequestHandler::ncml_build_dmr);
93 add_method(DAP4DATA_RESPONSE, NCMLRequestHandler::ncml_build_dmr);
95 add_method(VERS_RESPONSE, NCMLRequestHandler::ncml_build_vers);
96 add_method(HELP_RESPONSE, NCMLRequestHandler::ncml_build_help);
98 if (NCMLRequestHandler::_global_attributes_container_name_set ==
false) {
99 bool key_found =
false;
104 NCMLRequestHandler::_global_attributes_container_name_set =
true;
106 NCMLRequestHandler::_global_attributes_container_name = value;
111NCMLRequestHandler::~NCMLRequestHandler()
122bool NCMLRequestHandler::ncml_build_redirect(BESDataHandlerInterface &dhi,
const string& location)
133 BESContainerStorageList *store_list = BESContainerStorageList::TheList();
134 BESContainerStorage *store = store_list->find_persistence(
"catalog");
136 throw BESInternalError(
"couldn't find the catalog storage", __FILE__, __LINE__);
141 string new_sym = sym_name +
"_location1";
144 BESContainer *container = store->
look_for(new_sym);
146 throw BESInternalError(
"couldn't find the container" + sym_name, __FILE__, __LINE__);
148 BESContainer *ncml_container = dhi.
container;
153 BESRequestHandlerList::TheList()->execute_current(dhi);
166bool NCMLRequestHandler::ncml_build_das(BESDataHandlerInterface &dhi)
168 BES_STOPWATCH_START_DHI(MODULE, prolog +
"Timer", &dhi);
174 DDSLoader loader(dhi);
175 NCMLParser parser(loader);
176 unique_ptr<BESDapResponse> loaded_bdds = parser.parse(filename, DDSLoader::eRT_RequestDDX);
182 BESDASResponse *bdas =
dynamic_cast<BESDASResponse *
>(dhi.response_handler->
get_response_object());
186 DAS *das = bdas->get_das();
188 if (dds->get_dap_major() < 4)
189 NCMLUtil::hackGlobalAttributesForDAP2(dds->get_attr_table(),
190 NCMLRequestHandler::get_global_attributes_container_name());
198bool NCMLRequestHandler::ncml_build_dds(BESDataHandlerInterface &dhi)
202 BES_STOPWATCH_START_DHI(MODULE, prolog +
"Timer", &dhi);
208 unique_ptr<BESDapResponse> loaded_bdds(0);
210 DDSLoader loader(dhi);
211 NCMLParser parser(loader);
212 loaded_bdds = parser.parse(filename, DDSLoader::eRT_RequestDDX);
214 if (!loaded_bdds.get()) {
215 throw BESInternalError(
"Null BESDDSResonse in ncml DDS handler.", __FILE__, __LINE__);
222 BESDDSResponse *bdds_out =
dynamic_cast<BESDDSResponse *
>(response);
224 DDS *dds = bdds_out->
get_dds();
227 if (dds->get_dap_major() < 4)
228 NCMLUtil::hackGlobalAttributesForDAP2(dds->get_attr_table(),
229 NCMLRequestHandler::get_global_attributes_container_name());
243 dds->filename(name_path(filename));
244 dds->set_dataset_name(name_path(filename));
249 BES_STOPWATCH_START_DHI(MODULE, prolog +
"Timer", &dhi);
254 BESDDSResponse* ddsResponse =
dynamic_cast<BESDDSResponse *
>(dhi.response_handler->
get_response_object());
255 NCML_ASSERT_MSG(ddsResponse,
256 "NCMLRequestHandler::ncml_build_data(): expected BESDDSResponse* but didn't get it!!");
260 DDSLoader loader(dhi);
261 NCMLParser parser(loader);
262 parser.parseInto(filename, DDSLoader::eRT_RequestDDX, ddsResponse);
265 DDS *dds = ddsResponse->
get_dds();
268 if (dds->get_dap_major() < 4)
269 NCMLUtil::hackGlobalAttributesForDAP2(dds->get_attr_table(),
270 NCMLRequestHandler::get_global_attributes_container_name());
277 dds->filename(name_path(filename));
278 dds->set_dataset_name(name_path(filename));
283bool NCMLRequestHandler::ncml_build_data(BESDataHandlerInterface &dhi)
285 BES_STOPWATCH_START_DHI(MODULE, prolog +
"Timer", &dhi);
290 BESDataDDSResponse* dataResponse =
dynamic_cast<BESDataDDSResponse *
>(dhi.response_handler->
get_response_object());
291 NCML_ASSERT_MSG(dataResponse,
292 "NCMLRequestHandler::ncml_build_data(): expected BESDataDDSResponse* but didn't get it!!");
296 DDSLoader loader(dhi);
297 NCMLParser parser(loader);
298 parser.parseInto(filename, DDSLoader::eRT_RequestDataDDS, dataResponse);
313 dds->filename(name_path(filename));
314 dds->set_dataset_name(name_path(filename));
319bool NCMLRequestHandler::ncml_build_dmr(BESDataHandlerInterface &dhi)
321 BES_STOPWATCH_START_DHI(MODULE, prolog +
"Timer", &dhi);
329 unique_ptr<BESDapResponse> loaded_bdds;
331 DDSLoader loader(dhi);
332 NCMLParser parser(loader);
333 loaded_bdds = parser.parse(data_path, DDSLoader::eRT_RequestDDX);
334 if (!loaded_bdds.get())
throw BESInternalError(
"Null BESDDSResonse in the NCML DDS handler.", __FILE__, __LINE__);
337 dds->filename(data_path);
338 dds->set_dataset_name(data_path);
340 catch (InternalErr &e) {
341 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
344 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
350 throw BESDapError(
"Caught unknown error build ** DMR response",
true, unknown_error, __FILE__, __LINE__);
356 BESDMRResponse &bdmr =
dynamic_cast<BESDMRResponse &
>(*response);
361 DMR *dmr = bdmr.get_dmr();
362 dmr->set_factory(
new D4BaseTypeFactory);
363 dmr->build_using_dds(*dds);
376bool NCMLRequestHandler::ncml_build_vers(BESDataHandlerInterface &dhi)
378 BESVersionInfo *info =
dynamic_cast<BESVersionInfo *
>(dhi.response_handler->
get_response_object());
379 if (!info)
throw InternalErr(__FILE__, __LINE__,
"Expected a BESVersionInfo instance");
381 info->add_module(MODULE_NAME, MODULE_VERSION);
385bool NCMLRequestHandler::ncml_build_help(BESDataHandlerInterface &dhi)
388 if (!info)
throw InternalErr(__FILE__, __LINE__,
"Expected a BESVersionInfo instance");
392 map<string, string, std::less<>> attrs;
393 attrs[
"name"] = MODULE_NAME;
394 attrs[
"version"] = MODULE_VERSION;
396 list<string> services;
398 if (services.size() > 0) {
400 attrs[
"handles"] = handles;
402 info->begin_tag(
"module", &attrs);
405 info->end_tag(
"module");
412 strm << BESIndent::LMarg <<
"NCMLRequestHandler::dump - (" << (
void *)
this <<
")" << endl;
415 BESIndent::UnIndent();
virtual bool del_container(const std::string &s_name)=0
removes a container with the given symbolic name
virtual void add_container(const std::string &sym_name, const std::string &real_name, const std::string &type)=0
adds a container with the provided information
virtual BESContainer * look_for(const std::string &sym_name)=0
looks for a container in this persistent store
std::string get_symbolic_name() const
retrieve the symbolic name for this container
virtual std::string access()=0
returns the true name of this container
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
BESContainer * container
pointer to current container in this interface
virtual void add_data(const std::string &s)
add data to this informational object. If buffering is not set then the information is output directl...
Represents a specific data type request handler.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual BESResponseObject * get_response_object()
return the current response object
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
static std::string implode(const std::list< std::string > &values, char delim)
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.
virtual void dump(std::ostream &strm) const
dumps information about this object
static libdap::DDS * getDDSFromEitherResponse(BESDapResponse *response)
static void populateDASFromDDS(libdap::DAS *das, const libdap::DDS &dds_const)
static void copyVariablesAndAttributesInto(libdap::DDS *dds_out, const libdap::DDS &dds_in)
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
NcML Parser for adding/modifying/removing metadata (attributes) to existing local datasets using NcML...
static const std::string DOC_WIKI_URL
static const std::string NCML_NAME