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