37#include <libxml/parser.h>
47#include "CmdTranslation.h"
48#include "BESTokenizer.h"
49#include "BESSyntaxUserError.h"
51#define MY_ENCODING "ISO-8859-1"
53map<string, CmdTranslation::p_cmd_translator> CmdTranslation::_translations;
54bool CmdTranslation::_is_show =
false;
56int CmdTranslation::initialize(
int,
char**)
58 _translations[
"show"] = CmdTranslation::translate_show;
59 _translations[
"show.catalog"] = CmdTranslation::translate_catalog;
60 _translations[
"show.info"] = CmdTranslation::translate_catalog;
61 _translations[
"show.error"] = CmdTranslation::translate_show_error;
62 _translations[
"set"] = CmdTranslation::translate_set;
63 _translations[
"set.context"] = CmdTranslation::translate_context;
64 _translations[
"set.container"] = CmdTranslation::translate_container;
65 _translations[
"define"] = CmdTranslation::translate_define;
66 _translations[
"delete"] = CmdTranslation::translate_delete;
67 _translations[
"get"] = CmdTranslation::translate_get;
71int CmdTranslation::terminate(
void)
76void CmdTranslation::add_translation(
const string &name, p_cmd_translator func)
78 CmdTranslation::_translations[name] = func;
81void CmdTranslation::remove_translation(
const string &name)
83 map<string, p_cmd_translator>::iterator i = CmdTranslation::_translations.find(name);
84 if (i != CmdTranslation::_translations.end()) {
85 CmdTranslation::_translations.erase(i);
89string CmdTranslation::translate(
const string &commands)
100 catch (BESSyntaxUserError &e) {
101 cerr <<
"failed to build tokenizer for translation" << endl;
109 xmlTextWriterPtr writer = 0;
110 xmlBufferPtr buf = 0;
115 buf = xmlBufferCreate();
117 cerr <<
"testXmlwriterMemory: Error creating the xml buffer" << endl;
123 writer = xmlNewTextWriterMemory(buf, 0);
124 if (writer == NULL) {
125 cerr <<
"testXmlwriterMemory: Error creating the xml writer" << endl;
132 rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
134 cerr <<
"testXmlwriterMemory: Error at xmlTextWriterStartDocument" << endl;
135 xmlFreeTextWriter(writer);
141 rc = xmlTextWriterStartElement(writer, BAD_CAST
"request");
143 cerr <<
"testXmlwriterMemory: Error at xmlTextWriterStartElement" << endl;
144 xmlFreeTextWriter(writer);
149 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"reqID",
150 BAD_CAST
"some_unique_value");
152 cerr <<
"failed to add the request id attribute" << endl;
156 bool status = do_translate(t, writer);
158 xmlFreeTextWriter(writer);
163 rc = xmlTextWriterEndElement(writer);
165 cerr <<
"failed to close request element" << endl;
166 xmlFreeTextWriter(writer);
170 rc = xmlTextWriterEndDocument(writer);
172 cerr <<
"failed to end the document" << endl;
176 xmlFreeTextWriter(writer);
181 cerr <<
"failed to retrieve document as string" << endl;
184 doc = (
char *) buf->content;
194bool CmdTranslation::do_translate(
BESTokenizer &t, xmlTextWriterPtr writer)
197 CmdTranslation::p_cmd_translator p = _translations[token];
199 cerr << endl <<
"Invalid command " << token << endl << endl;
204 bool status = p(t, writer);
209 catch (BESSyntaxUserError &e) {
219 catch (BESSyntaxUserError &e) {
230 return do_translate(t, writer);
233bool CmdTranslation::translate_show(
BESTokenizer &t, xmlTextWriterPtr writer)
235 CmdTranslation::set_show(
true);
238 if (show_what.empty()) {
239 t.
parse_error(
"show command must be followed by target");
242 string new_cmd =
"show." + show_what;
243 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
250 string err = (string)
"show " + show_what +
" commands must end with a semicolon";
253 show_what[0] = toupper(show_what[0]);
254 string tag =
"show" + show_what;
257 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
259 cerr <<
"failed to start " << tag <<
" element" << endl;
264 rc = xmlTextWriterEndElement(writer);
266 cerr <<
"failed to close " << tag <<
" element" << endl;
273bool CmdTranslation::translate_show_error(
BESTokenizer &t, xmlTextWriterPtr writer)
276 if (show_what.empty() || show_what !=
"error") {
282 string err = (string)
"show " + show_what +
" command must include the error type to show";
288 string err = (string)
"show " + show_what +
" commands must end with a semicolon";
291 show_what[0] = toupper(show_what[0]);
292 string tag =
"show" + show_what;
295 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
297 cerr <<
"failed to start " << tag <<
" element" << endl;
302 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"type",
303 BAD_CAST etype.c_str());
305 cerr <<
"failed to add the get type attribute" << endl;
310 rc = xmlTextWriterEndElement(writer);
312 cerr <<
"failed to close " << tag <<
" element" << endl;
319bool CmdTranslation::translate_catalog(
BESTokenizer &t, xmlTextWriterPtr writer)
324 if (show_what.empty() || (show_what !=
"info" && show_what !=
"catalog")) {
325 t.
parse_error(
"show command must be info or catalog");
328 show_what[0] = toupper(show_what[0]);
329 string tag =
"show" + show_what;
333 if (token ==
"for") {
336 t.
parse_error(
"show catalog command expecting node");
342 t.
parse_error(
"show command must be terminated by a semicolon");
346 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
348 cerr <<
"failed to start " << tag <<
" element" << endl;
354 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"node",
355 BAD_CAST node.c_str());
357 cerr <<
"failed to add the catalog node attribute" << endl;
363 rc = xmlTextWriterEndElement(writer);
365 cerr <<
"failed to close " << tag <<
" element" << endl;
372bool CmdTranslation::translate_set(
BESTokenizer &t, xmlTextWriterPtr writer)
375 if (set_what.empty()) {
376 t.
parse_error(
"set command must be followed by target");
379 string new_cmd =
"set." + set_what;
380 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
382 cerr <<
"no such command: set " << set_what << endl;
389bool CmdTranslation::translate_context(
BESTokenizer &t, xmlTextWriterPtr writer)
399 t.
parse_error(
"missing word \"to\" in set context");
407 t.
parse_error(
"set context command must end with semicolon");
411 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"setContext");
413 cerr <<
"failed to start setContext element" << endl;
418 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"name",
419 BAD_CAST name.c_str());
421 cerr <<
"failed to add the context name attribute" << endl;
426 rc = xmlTextWriterWriteString(writer, BAD_CAST value.c_str());
428 cerr <<
"failed to write the value of the context" << endl;
433 rc = xmlTextWriterEndElement(writer);
435 cerr <<
"failed to close setContext element" << endl;
442bool CmdTranslation::translate_container(
BESTokenizer &t, xmlTextWriterPtr writer)
450 if (space ==
"values" || space ==
";") {
451 t.
parse_error(
"expecting name of container storage");
455 if (token !=
"values") {
460 if (name ==
";" || name ==
",") {
466 t.
parse_error(
"missing comma in set container after name");
470 if (value ==
"," || value ==
";") {
471 t.
parse_error(
"expecting location of the container");
485 t.
parse_error(
"set container command must end with semicolon");
489 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"setContainer");
491 cerr <<
"failed to start setContext element" << endl;
496 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"name",
497 BAD_CAST name.c_str());
499 cerr <<
"failed to add the context name attribute" << endl;
503 if (!space.empty()) {
505 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"space",
506 BAD_CAST space.c_str());
508 cerr <<
"failed to add the container space attribute" << endl;
515 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"type",
516 BAD_CAST type.c_str());
518 cerr <<
"failed to add the container type attribute" << endl;
524 rc = xmlTextWriterWriteString(writer, BAD_CAST value.c_str());
526 cerr <<
"failed to write the location of the container" << endl;
531 rc = xmlTextWriterEndElement(writer);
533 cerr <<
"failed to close setContext element" << endl;
540bool CmdTranslation::translate_define(
BESTokenizer &t, xmlTextWriterPtr writer)
560 t.
parse_error(
"Looking for keyword as in define command");
563 list<string> containers;
564 map<string, string> clist;
568 containers.push_back(token);
569 clist[token] = token;
577 map<string, string> constraints;
578 string default_constraint;
579 map<string, string> attrs;
580 if (token ==
"with") {
583 while (token !=
"aggregate" && token !=
";") {
585 if (token ==
"constraint") {
591 t.
parse_error(
"constraint container does not exist");
597 else if (type == 2) {
614 if (token ==
"aggregate") {
619 if (token !=
"using") {
620 t.
parse_error(
"aggregation expecting keyword \"using\"");
624 else if (token ==
"using") {
628 t.
parse_error(
"aggregation expecting keyword \"by\"");
633 t.
parse_error(
"aggregation expecting keyword \"by\" or \"using\"");
640 t.
parse_error(
"define command must end with semicolon");
644 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"define");
646 cerr <<
"failed to start setContext element" << endl;
651 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"name",
652 BAD_CAST name.c_str());
654 cerr <<
"failed to add the context name attribute" << endl;
658 if (!space.empty()) {
660 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"space",
661 BAD_CAST space.c_str());
663 cerr <<
"failed to add the container space attribute" << endl;
669 if (!default_constraint.empty()) {
671 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"constraint");
673 cerr <<
"failed to start container constraint element" << endl;
678 rc = xmlTextWriterWriteString(writer, BAD_CAST default_constraint.c_str());
680 cerr <<
"failed to write constraint for container" << endl;
685 rc = xmlTextWriterEndElement(writer);
687 cerr <<
"failed to close constraint element" << endl;
692 list<string>::iterator i = containers.begin();
693 list<string>::iterator e = containers.end();
694 for (; i != e; i++) {
696 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"container");
698 cerr <<
"failed to start container element" << endl;
703 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"name",
704 BAD_CAST (*i).c_str());
706 cerr <<
"failed to add the context name attribute" << endl;
711 string constraint = constraints[(*i)];
712 if (!constraint.empty()) {
714 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"constraint");
716 cerr <<
"failed to start container constraint element" << endl;
721 rc = xmlTextWriterWriteString(writer, BAD_CAST constraint.c_str());
723 cerr <<
"failed to write constraint for container" << endl;
728 rc = xmlTextWriterEndElement(writer);
730 cerr <<
"failed to close constraint element" << endl;
735 string attr = attrs[(*i)];
738 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"attributes");
740 cerr <<
"failed to start container attributes element" << endl;
745 rc = xmlTextWriterWriteString(writer, BAD_CAST attr.c_str());
747 cerr <<
"failed to write attributes for container" << endl;
752 rc = xmlTextWriterEndElement(writer);
754 cerr <<
"failed to close attributes element" << endl;
760 rc = xmlTextWriterEndElement(writer);
762 cerr <<
"failed to close setContext element" << endl;
767 if (!agg_cmd.empty()) {
769 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"aggregate");
771 cerr <<
"failed to start aggregate element" << endl;
775 if (!agg_handler.empty()) {
777 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"handler",
778 BAD_CAST agg_handler.c_str());
780 cerr <<
"failed to add the context name attribute" << endl;
786 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"cmd",
787 BAD_CAST agg_cmd.c_str());
789 cerr <<
"failed to add the context name attribute" << endl;
794 rc = xmlTextWriterEndElement(writer);
796 cerr <<
"failed to close setContext element" << endl;
802 rc = xmlTextWriterEndElement(writer);
804 cerr <<
"failed to close setContext element" << endl;
811bool CmdTranslation::translate_delete(
BESTokenizer &t, xmlTextWriterPtr writer)
824 string new_cmd =
"delete." + del_what;
826 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
832 if (del_what ==
"container" || del_what ==
"definition") {
835 else if (del_what ==
"containers" || del_what ==
"definitions") {
842 del_what[0] = toupper(del_what[0]);
843 string tag =
"delete" + del_what;
852 if (token ==
"from") {
858 t.
parse_error(
"delete command expected to end with semicolon");
862 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
864 cerr <<
"failed to start aggregate element" << endl;
870 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"name",
871 BAD_CAST name.c_str());
873 cerr <<
"failed to add the context name attribute" << endl;
878 if (!space.empty()) {
880 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"space",
881 BAD_CAST space.c_str());
883 cerr <<
"failed to add the context name attribute" << endl;
889 rc = xmlTextWriterEndElement(writer);
891 cerr <<
"failed to close setContext element" << endl;
898bool CmdTranslation::translate_get(
BESTokenizer &t, xmlTextWriterPtr writer)
906 if (token !=
"for") {
907 t.
parse_error(
"get command expecting keyword \"for\"");
918 if (token ==
"return") {
921 t.
parse_error(
"get command expecting keyword \"as\" for return");
926 else if (token ==
"using") {
930 else if (token ==
"contentStartId") {
934 else if (token ==
"mimeBoundary") {
938 else if (token ==
";") {
947 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"get");
949 cerr <<
"failed to start aggregate element" << endl;
954 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"type",
955 BAD_CAST get_what.c_str());
957 cerr <<
"failed to add the get type attribute" << endl;
962 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"definition",
963 BAD_CAST def_name.c_str());
965 cerr <<
"failed to add the get definition attribute" << endl;
971 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"url",
972 BAD_CAST url.c_str());
974 cerr <<
"failed to add the url attribute" << endl;
979 if (!returnAs.empty()) {
981 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST
"returnAs",
982 BAD_CAST returnAs.c_str());
984 cerr <<
"failed to add the returnAs attribute" << endl;
989 if (!starting.empty()) {
991 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"contentStartId");
993 cerr <<
"failed to start contentStartId element" << endl;
998 rc = xmlTextWriterWriteString(writer, BAD_CAST starting.c_str());
1000 cerr <<
"failed to write contentStartId for get request" << endl;
1005 rc = xmlTextWriterEndElement(writer);
1007 cerr <<
"failed to close constraint element" << endl;
1012 if (!bounding.empty()) {
1014 int rc = xmlTextWriterStartElement(writer, BAD_CAST
"mimeBoundary");
1016 cerr <<
"failed to start mimeBoundary element" << endl;
1021 rc = xmlTextWriterWriteString(writer, BAD_CAST bounding.c_str());
1023 cerr <<
"failed to write mimeBoundary for get request" << endl;
1028 rc = xmlTextWriterEndElement(writer);
1030 cerr <<
"failed to close mimeBoundary element" << endl;
1036 rc = xmlTextWriterEndElement(writer);
1038 cerr <<
"failed to close get element" << endl;
1045void CmdTranslation::dump(ostream &strm)
1047 strm << BESIndent::LMarg <<
"CmdTranslation::dump" << endl;
1048 BESIndent::Indent();
1049 if (_translations.empty()) {
1050 strm << BESIndent::LMarg <<
"NO translations registered" << endl;
1053 strm << BESIndent::LMarg <<
"translations registered" << endl;
1054 BESIndent::Indent();
1055 map<string, p_cmd_translator>::iterator i = _translations.begin();
1056 map<string, p_cmd_translator>::iterator e = _translations.end();
1057 for (; i != e; i++) {
1058 strm << BESIndent::LMarg << (*i).first << endl;
1060 BESIndent::UnIndent();
1062 BESIndent::UnIndent();
std::string get_message() const
get the error message for this exception
tokenizer for the BES request command string
void parse_error(const std::string &s="")
throws an exception giving the tokens up to the point of the problem
void tokenize(const char *p)
tokenize the BES request/command string
std::string remove_quotes(const std::string &s)
removes quotes from a quoted token
std::string parse_container_name(const std::string &s, unsigned int &type)
parses a container name for constraint and attributes
std::string & get_current_token()
returns the current token from the token list
std::string & get_first_token()
returns the first token from the token list
std::string & get_next_token()
returns the next token from the token list