bes  Updated for version 3.20.10
XMLSetContextsCommand.cc
1 // XMLSetContextsCommand.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2018 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 #include "XMLSetContextsCommand.h"
28 
29 #include "BESXMLUtils.h"
30 #include "BESUtil.h"
31 #include "BESDataNames.h"
32 #include "BESSyntaxUserError.h"
33 #include "BESDebug.h"
34 
35 #include "SetContextsNames.h"
36 
37 #if !USE_CONTEXTS_RESPONSE_HANDLER
38 #include "BESContextManager.h"
39 #endif
40 
41 using namespace bes;
42 using namespace std;
43 
64 {
65  string value, name, action;
66  map<string, string> props;
67  BESXMLUtils::GetNodeInfo(node, action, value, props);
68  if (action != SET_CONTEXTS_STR) {
69  string err = "The specified command " + action + " is not a set context command";
70  throw BESSyntaxUserError(err, __FILE__, __LINE__);
71  }
72 
73  xmlNode *current_node = node->children;
74  while (current_node) {
75  if (current_node->type == XML_ELEMENT_NODE) {
76 
77  string name, value;
78  map<string, string> attributes;
79  BESXMLUtils::GetNodeInfo(current_node, name, value, attributes);
80 
81  if (name != "context")
82  throw BESSyntaxUserError(string("Inside setContexts, expected a 'context' but got '"
83  + name +"'."), __FILE__, __LINE__);
84 
85  if (value.empty())
86  throw BESSyntaxUserError(string("The 'context' element must contain a value"), __FILE__,
87  __LINE__);
88 
89  if (attributes.size() != 1 || attributes["name"].empty())
90  throw BESSyntaxUserError(string("The 'context' element must contain a 'name' attribute."),
91  __FILE__, __LINE__);
92 
93  // Set the context _or_ push the information into the DHI data[] map
94 #if USE_CONTEXTS_RESPONSE_HANDLER
95  // To record the information in the DHI data[] map, use one value to hold a
96  // list of all of Context names, then use the names to hold the values. Read
97  // this using names = data[CONTEXT_NAMES] and then:
98  //
99  // for each 'name' in names { value = data['context_'name] }
100  //
101  string context_key = string(CONTEXT_PREFIX).append(attributes["name"]);
102  d_xmlcmd_dhi.data[CONTEXT_NAMES] = d_xmlcmd_dhi.data[CONTEXT_NAMES].append(" ").append(context_key);
103  d_xmlcmd_dhi.data[context_key] = value;
104 
105  BESDEBUG("besxml", "d_xmlcmd_dhi.data[" << context_key << "] = " << value << endl);
106 #else
107  BESDEBUG("besxml", "In " << __func__ << " BESContextManager::TheManager()->set_context("
108  << name << ", " << value << ")" << endl);
109 
110  BESContextManager::TheManager()->set_context(attributes["name"], value);
111 #endif
112  }
113 
114  current_node = current_node->next;
115  }
116 
117  d_cmd_log_info = string("set contexts for ").append(d_xmlcmd_dhi.data[CONTEXT_NAMES]);
118 
119 
120 #if USE_CONTEXTS_RESPONSE_HANDLER
121  // The value set to DHI's action field is used to choose the matching ResponseHandler.
122  d_xmlcmd_dhi.action = SET_CONTEXTS_ACTION;
123 #else
124  // Set action_name here because the NULLResponseHandler (aka NULL_ACTION) won't know
125  // which command used it (current ResponseHandlers set this because there is a 1-to-1
126  // correlation between XMLCommands and ResponseHanlders). jhrg 2/8/18
127  d_xmlcmd_dhi.action_name = SET_CONTEXTS_STR;
128  d_xmlcmd_dhi.action = NULL_ACTION;
129 #endif
130 
131  // Set the response handler for the action in the command's DHI using the value of
132  // the DHI.action field. And, as a bonus, copy the d_cmd_log_info into DHI.data[LOG_INFO]
133  // and if VERBOSE logging is on, log that the command has been parsed.
135 }
136 
143 void XMLSetContextsCommand::dump(ostream &strm) const
144 {
145  strm << BESIndent::LMarg << "XMLSetContextsCommand::dump - (" << (void *) this << ")" << endl;
146  BESIndent::Indent();
147  BESXMLCommand::dump(strm);
148  BESIndent::UnIndent();
149 }
150 
152 XMLSetContextsCommand::CommandBuilder(const BESDataHandlerInterface &base_dhi)
153 {
154  return new XMLSetContextsCommand(base_dhi);
155 }
156 
virtual void set_context(const std::string &name, const std::string &value)
set context in the BES
Structure storing information used by the BES to handle the request.
error thrown if there is a user syntax error in the request or any other user error
Base class for the BES's commands.
Definition: BESXMLCommand.h:63
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.
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
Definition: BESXMLUtils.cc:109
virtual void parse_request(xmlNode *node)
parse a setContexts command.
virtual void dump(std::ostream &strm) const
dumps information about this object