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__);
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";
247 throw BESSyntaxUserError(err, __FILE__, __LINE__);
251 if (child_value.empty()) {
252 string err = action +
" command: constraint element " +
"missing value";
253 throw BESSyntaxUserError(err, __FILE__, __LINE__);
256 if (have_constraint) {
257 string err = action +
" command: container element " +
"contains multiple constraint elements";
258 throw BESSyntaxUserError(err, __FILE__, __LINE__);
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";
266 throw BESSyntaxUserError(err, __FILE__, __LINE__);
270 if (child_value.empty()) {
271 string err = action +
" command: constraint element " +
"missing value";
272 throw BESSyntaxUserError(err, __FILE__, __LINE__);
275 if (have_dap4constraint) {
276 string err = action +
" command: container element " +
"contains multiple constraint elements";
277 throw BESSyntaxUserError(err, __FILE__, __LINE__);
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";
285 throw BESSyntaxUserError(err, __FILE__, __LINE__);
287 if (child_value.empty()) {
288 string err = action +
" command: dap4_function element " +
"missing value";
289 throw BESSyntaxUserError(err, __FILE__, __LINE__);
291 if (have_dap4function) {
292 string err = action +
" command: container element " +
"contains multiple dap4_function elements";
293 throw BESSyntaxUserError(err, __FILE__, __LINE__);
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";
301 throw BESSyntaxUserError(err, __FILE__, __LINE__);
303 if (child_value.empty()) {
304 string err = action +
" command: attributes element " +
"missing value";
305 throw BESSyntaxUserError(err, __FILE__, __LINE__);
307 if (have_attributes) {
308 string err = action +
" command: container element " +
"contains multiple attributes elements";
309 throw BESSyntaxUserError(err, __FILE__, __LINE__);
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";
344 throw BESSyntaxUserError(err, __FILE__, __LINE__);
347 string err = action +
" command: must specify aggregation cmd";
348 throw BESSyntaxUserError(err, __FILE__, __LINE__);
351 d_xmlcmd_dhi.data[AGG_HANDLER] = handler;
352 d_xmlcmd_dhi.data[AGG_CMD] = cmd;
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();
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.
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