35#include "BESXMLDefineCommand.h"
36#include "BESContainerStorageList.h"
37#include "BESContainerStorage.h"
39#include "BESXMLUtils.h"
41#include "BESResponseNames.h"
42#include "BESDataNames.h"
44#include "BESSyntaxUserError.h"
45#include "BESInternalFatalError.h"
55 BESXMLCommand(base_dhi), _default_constraint(
""), _default_dap4_constraint(
""), _default_dap4_function(
"")
91 map<string, string> props;
94 if (action != DEFINE_RESPONSE_STR) {
95 string err =
"The specified command " + action +
" is not a set context command";
99 d_xmlcmd_dhi.
action = DEFINE_RESPONSE;
101 string def_name = props[
"name"];
102 if (def_name.empty())
103 throw BESSyntaxUserError(
string(action) +
" command: definition name missing", __FILE__, __LINE__);
105 d_xmlcmd_dhi.
data[DEF_NAME] = def_name;
108 d_xmlcmd_dhi.
data[STORE_NAME] = props[
"space"].empty() ? DEFAULT: props[
"space"];
111 int num_containers = 0;
117 if (child_name ==
"constraint") {
119 _default_constraint = child_value;
121 else if (child_name ==
"dap4constraint") {
123 _default_dap4_constraint = child_value;
125 else if (child_name ==
"dap4function") {
127 _default_dap4_function = child_value;
129 else if (child_name ==
"container") {
130 handle_container_element(action, child_node, child_value, props);
134 throw BESSyntaxUserError(
string(action) +
" Unrecognized child element: " + child_name, __FILE__, __LINE__);
137 else if (child_name ==
"aggregate") {
138 handle_aggregate_element(action, child_node, child_value, props);
149 if (num_containers < 1)
150 throw BESSyntaxUserError(
string(action) +
" The define element must contain at least one container element", __FILE__, __LINE__);
154 vector<string>::iterator i = container_names.begin();
155 vector<string>::iterator e = container_names.end();
156 for (; i != e; i++) {
162 if (container_constraints.size() || container_dap4constraints.size() || container_dap4functions.size() || container_attributes.size()) {
165 i = container_names.begin();
166 e = container_names.end();
167 for (; i != e; i++) {
168 if (container_constraints.count((*i))) {
171 d_cmd_log_info += (*i) +
".constraint=\"" + container_constraints[(*i)] +
"\"";
173 if (container_dap4constraints.count((*i))) {
176 d_cmd_log_info += (*i) +
".dap4constraint=\"" + container_dap4constraints[(*i)] +
"\"";
178 if (container_dap4functions.count((*i))) {
181 d_cmd_log_info += (*i) +
".dap4function=\"" + container_dap4functions[(*i)] +
"\"";
183 if (container_attributes.count((*i))) {
186 d_cmd_log_info += (*i) +
".attributes=\"" + container_attributes[(*i)] +
"\"";
220void BESXMLDefineCommand::handle_container_element(
const string &action, xmlNode *node,
const string &,
221 map<string, string> &props)
223 string name = props[
"name"];
225 string err = action +
" command: container element missing name prop";
229 container_names.push_back(name);
231 container_store_names[name] = props[
"space"];
233 bool have_constraint =
false;
234 bool have_dap4constraint =
false;
235 bool have_dap4function =
false;
236 bool have_attributes =
false;
241 map<string, string> child_props;
244 if (child_name ==
"constraint") {
245 if (child_props.size()) {
246 string err = action +
" command: constraint element " +
"should not contain properties";
251 if (child_value.empty()) {
252 string err = action +
" command: constraint element " +
"missing value";
256 if (have_constraint) {
257 string err = action +
" command: container element " +
"contains multiple constraint elements";
260 have_constraint =
true;
261 container_constraints[name] = child_value;
263 else if (child_name ==
"dap4constraint") {
264 if (child_props.size()) {
265 string err = action +
" command: constraint element " +
"should not contain properties";
270 if (child_value.empty()) {
271 string err = action +
" command: constraint element " +
"missing value";
275 if (have_dap4constraint) {
276 string err = action +
" command: container element " +
"contains multiple constraint elements";
279 have_dap4constraint =
true;
280 container_dap4constraints[name] = child_value;
282 else if (child_name ==
"dap4function") {
283 if (child_props.size()) {
284 string err = action +
" command: dap4_function element " +
"should not contain properties";
287 if (child_value.empty()) {
288 string err = action +
" command: dap4_function element " +
"missing value";
291 if (have_dap4function) {
292 string err = action +
" command: container element " +
"contains multiple dap4_function elements";
295 have_dap4function =
true;
296 container_dap4functions[name] = child_value;
298 else if (child_name ==
"attributes") {
299 if (child_props.size()) {
300 string err = action +
" command: attributes element " +
"should not contain properties";
303 if (child_value.empty()) {
304 string err = action +
" command: attributes element " +
"missing value";
307 if (have_attributes) {
308 string err = action +
" command: container element " +
"contains multiple attributes elements";
311 have_attributes =
true;
312 container_attributes[name] = child_value;
337void BESXMLDefineCommand::handle_aggregate_element(
const string &action, xmlNode *,
const string &,
338 map<string, string> &props)
340 string handler = props[
"handler"];
341 string cmd = props[
"cmd"];
342 if (handler.empty()) {
343 string err = action +
" command: must specify aggregation handler";
347 string err = action +
" command: must specify aggregation cmd";
351 d_xmlcmd_dhi.
data[AGG_HANDLER] = handler;
352 d_xmlcmd_dhi.
data[AGG_CMD] = cmd;
368 vector<string>::iterator i = container_names.begin();
369 vector<string>::iterator e = container_names.end();
370 for (; i != e; i++) {
376 string store = container_store_names[(*i)];
377 if (!store.empty()) {
382 c = BESContainerStorageList::TheList()->
look_for((*i));
386 throw BESSyntaxUserError(
string(
"Could not find the container ") + (*i), __FILE__, __LINE__);
389 string constraint = container_constraints[(*i)];
390 if (constraint.empty()) constraint = _default_constraint;
394 string dap4constraint = container_dap4constraints[(*i)];
395 if (dap4constraint.empty()) dap4constraint = _default_dap4_constraint;
399 string function = container_dap4functions[(*i)];
400 if (function.empty()) function = _default_dap4_function;
403 string attrs = container_attributes[(*i)];
405 d_xmlcmd_dhi.containers.push_back(c);
407 BESDEBUG(
"xml",
"BESXMLDefineCommand::prep_request() - define using container: " << endl << *c << endl);
420 strm << BESIndent::LMarg <<
"BESXMLDefineCommand::dump - (" << (
void *)
this <<
")" << endl;
423 BESIndent::UnIndent();
virtual BESContainer * look_for(const std::string &sym_name)
look for the specified container information in the list of persistent stores.
virtual BESContainerStorage * find_persistence(const std::string &persist_name)
find the persistence store with the given name
provides persistent storage for data storage information represented by a container.
virtual BESContainer * look_for(const std::string &sym_name)=0
looks for a container in this persistent store
A container is something that holds data. E.G., a netcdf file or a database entry.
void set_constraint(const std::string &s)
set the constraint for this container
void set_dap4_function(const std::string &s)
set the constraint for this container
void set_attributes(const std::string &attrs)
set desired attributes for this container
void set_dap4_constraint(const std::string &s)
set the constraint for this container
Structure storing information used by the BES to handle the request.
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
std::string action
the response object requested, e.g. das, dds
exception thrown if an internal error is found and is fatal to the BES
error thrown if there is a user syntax error in the request or any other user error
Base class for the BES's commands.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void set_response()
The request has been parsed, use the command action name to set the response handler.
std::string d_cmd_log_info
Used only for the log.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void prep_request()
prepare the define command by making sure the containers exist
virtual void parse_request(xmlNode *node)
parse a define command.
static void GetNodeInfo(xmlNode *node, std::string &name, std::string &value, std::map< std::string, std::string > &props)
get the name, value if any, and any properties for the specified node
static xmlNode * GetFirstChild(xmlNode *node, std::string &child_name, std::string &child_value, std::map< std::string, std::string > &child_props)
get the first element child node for the given node
static xmlNode * GetNextChild(xmlNode *child_node, std::string &next_name, std::string &next_value, std::map< std::string, std::string > &next_props)
get the next element child node after the given child node