40 #include "BESXMLInterface.h" 41 #include "BESXMLCommand.h" 42 #include "BESXMLUtils.h" 43 #include "BESDataNames.h" 45 #include "BESResponseHandler.h" 46 #include "BESReturnManager.h" 48 #include "BESStopWatch.h" 52 #include "BESSyntaxUserError.h" 54 #define LOG_ONLY_GET_COMMANDS 56 BESXMLInterface::BESXMLInterface(
const string &xml_doc, ostream *strm) :
61 d_dhi_ptr = &d_xml_interface_dhi;
64 BESXMLInterface::~BESXMLInterface()
73 BESDEBUG(
"bes",
"Entering: " << __PRETTY_FUNCTION__ << endl);
74 BESDEBUG(
"bes",
"building request plan for xml document: " << endl << d_xml_document << endl);
84 xmlNode *root_element = NULL;
85 xmlNode *current_node = NULL;
89 vector<string> parseerrors;
93 doc = xmlReadMemory(d_xml_document.c_str(), d_xml_document.size(),
"" ,
94 NULL , XML_PARSE_NONET );
97 string err =
"Problem parsing the request xml document:\n";
99 vector<string>::const_iterator i = parseerrors.begin();
100 vector<string>::const_iterator e = parseerrors.end();
101 for (; i != e; i++) {
102 if (!isfirst && (*i).compare(0, 6,
"Entity") == 0) {
112 root_element = xmlDocGetRootElement(doc);
113 if (!root_element)
throw BESSyntaxUserError(
"There is no root element in the xml document", __FILE__, __LINE__);
117 map<string, string> props;
119 if (root_name !=
"request")
121 string(
"The root element should be a request element, name is ").append((
char *) root_element->name),
124 if (!root_val.empty())
125 throw BESSyntaxUserError(
string(
"The request element must not contain a value, ").append(root_val),
129 string &reqId = props[REQUEST_ID];
130 if (reqId.empty())
throw BESSyntaxUserError(
"The request id value empty", __FILE__, __LINE__);
134 BESDEBUG(
"besxml",
"request id = " <<
d_dhi_ptr->
data[REQUEST_ID] << endl);
138 bool has_response =
false;
139 current_node = root_element->children;
141 while (current_node) {
142 if (current_node->type == XML_ELEMENT_NODE) {
145 string node_name = (
char *) current_node->name;
154 throw BESSyntaxUserError(
string(
"Unable to find command for ").append(node_name), __FILE__,
159 throw BESInternalError(
string(
"Failed to build command object for ").append(node_name), __FILE__,
163 d_xml_cmd_list.push_back(current_cmd);
167 if (has_response && cmd_has_response)
168 throw BESSyntaxUserError(
"Commands with multiple responses not supported.", __FILE__, __LINE__);
170 has_response = cmd_has_response;
182 string return_as = current_dhi.
data[RETURN_CMD];
183 if (!return_as.empty() & !BESReturnManager::TheManager()->find_transmitter(return_as))
184 throw BESSyntaxUserError(
string(
"Unable to find transmitter ").append(return_as), __FILE__,
188 current_node = current_node->next;
211 BESDEBUG(
"bes",
"Done building request plan" << endl);
218 vector<BESXMLCommand *>::iterator i = d_xml_cmd_list.begin();
219 vector<BESXMLCommand *>::iterator e = d_xml_cmd_list.end();
220 for (; i != e; i++) {
221 (*i)->prep_request();
232 #ifdef LOG_ONLY_GET_COMMANDS 239 new_log_info.append(
",").append(
d_dhi_ptr->
data[RETURN_CMD]);
245 if (!c->
access().empty()) new_log_info.append(
",").append(c->
access());
256 LOG(new_log_info << endl);
259 LOG(
"Warning: The previous command had multiple containers defined, but only the was logged.");
292 LOG(
"Transmitting error: " << strm.str() << endl);
304 if (!return_as.empty()) {
305 d_transmitter = BESReturnManager::TheManager()->find_transmitter(return_as);
307 throw BESSyntaxUserError(
string(
"Unable to find transmitter ") + return_as, __FILE__, __LINE__);
324 if (BESLog::TheLog()->is_verbose()) {
325 vector<BESXMLCommand *>::iterator i = d_xml_cmd_list.begin();
326 vector<BESXMLCommand *>::iterator e = d_xml_cmd_list.end();
327 for (; i != e; i++) {
344 vector<BESXMLCommand *>::iterator i = d_xml_cmd_list.begin();
345 vector<BESXMLCommand *>::iterator e = d_xml_cmd_list.end();
346 for (; i != e; i++) {
360 d_xml_cmd_list.clear();
371 strm << BESIndent::LMarg <<
"BESXMLInterface::dump - (" << (
void *)
this <<
")" << endl;
374 vector<BESXMLCommand *>::const_iterator i = d_xml_cmd_list.begin();
375 vector<BESXMLCommand *>::const_iterator e = d_xml_cmd_list.end();
376 for (; i != e; i++) {
380 BESIndent::UnIndent();
void clean()
clean up any information created within this data handler interface
virtual void dump(ostream &strm) const
dumps information about this object
exception thrown if inernal error encountered
virtual void dump(ostream &strm) const
dumps information about this object
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)=0
transmit the response object built by the execute command using the specified transmitter object
static void GetNodeInfo(xmlNode *node, string &name, string &value, map< string, string > &props)
get the name, value if any, and any properties for the specified node
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)=0
transmit the informational object
bool is_verbose()
Returns true if verbose logging is requested.
BESDataHandlerInterface * d_dhi_ptr
Allocated by the child class.
virtual void execute(BESDataHandlerInterface &dhi)=0
knows how to build a requested response object
virtual void parse_request(xmlNode *node)=0
Parse the XML request document beginning at the given node.
string get_dap4_constraint() const
retrieve the constraint expression for this container
BESTransmitter * d_transmitter
The Transmitter to use for the result.
virtual void log_status()
Log the status of the request to the BESLog file.
virtual bool start(string name)
error thrown if there is a user syntax error in the request or any other user error
virtual string access()=0
returns the true name of this container
virtual void build_data_request_plan()
Build the data request plan using the BESCmdParser.
static p_xmlcmd_builder find_command(const std::string &cmd_str)
Find the BESXMLCommand creation function with the given name.
virtual void execute_data_request_plan()
Execute the data request plan.
static void XMLErrorFunc(void *context, const char *msg,...)
error function used by libxml2 to report errors
virtual void clean()
Clean up after the request is completed.
Entry point into BES, building responses to given requests.
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
string get_constraint() const
retrieve the constraint expression for this container
virtual void transmit_data()
Transmit the response object.
BESInfo * error_info
error information object
A container is something that holds data. I.E. a netcdf file or a database entry.
virtual BESDataHandlerInterface & get_xmlcmd_dhi()
Return the current BESDataHandlerInterface.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void print(ostream &strm)
print the information from this informational object to the specified stream
virtual bool has_response()=0
Has a response handler been created given the request document?
string action
the response object requested, e.g. das, dds
string get_dap4_function() const
retrieve the constraint expression for this container