bes Updated for version 3.20.13
CmdTranslation.cc
1// CmdTranslation.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) 2004-2009 University Corporation for Atmospheric Research
7// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
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 University Corporation for Atmospheric Research at
24// 3080 Center Green Drive, Boulder, CO 80301
25
26// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27// Please read the full copyright statement in the file COPYRIGHT_UCAR.
28//
29// Authors:
30// pwest Patrick West <pwest@ucar.edu>
31// jgarcia Jose Garcia <jgarcia@ucar.edu>
32
33#include <iostream>
34#include <list>
35#include <map>
36
37using std::cerr;
38using std::cout;
39using std::list;
40using std::map;
41using std::endl;
42using std::ostream ;
43using std::string;
44
45#include "CmdTranslation.h"
46#include "BESTokenizer.h"
47#include "BESSyntaxUserError.h"
48
49#define MY_ENCODING "ISO-8859-1"
50
51map<string, CmdTranslation::p_cmd_translator> CmdTranslation::_translations;
52bool CmdTranslation::_is_show = false;
53
54int CmdTranslation::initialize(int, char**)
55{
56 _translations["show"] = CmdTranslation::translate_show;
57 _translations["show.catalog"] = CmdTranslation::translate_catalog;
58 _translations["show.info"] = CmdTranslation::translate_catalog;
59 _translations["show.error"] = CmdTranslation::translate_show_error;
60 _translations["set"] = CmdTranslation::translate_set;
61 _translations["set.context"] = CmdTranslation::translate_context;
62 _translations["set.container"] = CmdTranslation::translate_container;
63 _translations["define"] = CmdTranslation::translate_define;
64 _translations["delete"] = CmdTranslation::translate_delete;
65 _translations["get"] = CmdTranslation::translate_get;
66 return 0;
67}
68
69int CmdTranslation::terminate(void)
70{
71 return 0;
72}
73
74void CmdTranslation::add_translation(const string &name, p_cmd_translator func)
75{
76 CmdTranslation::_translations[name] = func;
77}
78
79void CmdTranslation::remove_translation(const string &name)
80{
81 map<string, p_cmd_translator>::iterator i = CmdTranslation::_translations.find(name);
82 if (i != CmdTranslation::_translations.end()) {
83 CmdTranslation::_translations.erase(i);
84 }
85}
86
87string CmdTranslation::translate(const string &commands)
88{
90 try {
91 t.tokenize(commands.c_str());
92
93 string token = t.get_first_token();
94 if (token.empty()) {
95 return "";
96 }
97 }
98 catch (BESSyntaxUserError &e) {
99 cerr << "failed to build tokenizer for translation" << endl;
100 cerr << e.get_message() << endl;
101 return "";
102 }
103
104 LIBXML_TEST_VERSION;
105
106 int rc;
107 xmlTextWriterPtr writer = 0;
108 xmlBufferPtr buf = 0;
109 // Unused xmlChar *tmp = 0;
110
111 /* Create a new XML buffer, to which the XML document will be
112 * written */
113 buf = xmlBufferCreate();
114 if (buf == NULL) {
115 cerr << "testXmlwriterMemory: Error creating the xml buffer" << endl;
116 return "";
117 }
118
119 /* Create a new XmlWriter for memory, with no compression.
120 * Remark: there is no compression for this kind of xmlTextWriter */
121 writer = xmlNewTextWriterMemory(buf, 0);
122 if (writer == NULL) {
123 cerr << "testXmlwriterMemory: Error creating the xml writer" << endl;
124 return "";
125 }
126
127 /* Start the document with the xml default for the version,
128 * encoding ISO 8859-1 and the default for the standalone
129 * declaration. MY_ENCODING defined at top of this file*/
130 rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
131 if (rc < 0) {
132 cerr << "testXmlwriterMemory: Error at xmlTextWriterStartDocument" << endl;
133 xmlFreeTextWriter(writer);
134 return "";
135 }
136
137 /* Start an element named "request". Since thist is the first
138 * element, this will be the root element of the document. */
139 rc = xmlTextWriterStartElement(writer, BAD_CAST "request");
140 if (rc < 0) {
141 cerr << "testXmlwriterMemory: Error at xmlTextWriterStartElement" << endl;
142 xmlFreeTextWriter(writer);
143 return "";
144 }
145
146 /* Add the request id attribute */
147 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "reqID",
148 BAD_CAST "some_unique_value");
149 if (rc < 0) {
150 cerr << "failed to add the request id attribute" << endl;
151 return "";
152 }
153
154 bool status = do_translate(t, writer);
155 if (!status) {
156 xmlFreeTextWriter(writer);
157 return "";
158 }
159
160 // this should end the request element
161 rc = xmlTextWriterEndElement(writer);
162 if (rc < 0) {
163 cerr << "failed to close request element" << endl;
164 xmlFreeTextWriter(writer);
165 return "";
166 }
167
168 rc = xmlTextWriterEndDocument(writer);
169 if (rc < 0) {
170 cerr << "failed to end the document" << endl;
171 return "";
172 }
173
174 xmlFreeTextWriter(writer);
175
176 // get the xml document as a string and return
177 string doc;
178 if (!buf->content) {
179 cerr << "failed to retrieve document as string" << endl;
180 }
181 else {
182 doc = (char *) buf->content;
183 }
184
185 xmlBufferFree(buf);
186
187 xmlCleanupParser();
188
189 return doc;
190}
191
192bool CmdTranslation::do_translate(BESTokenizer &t, xmlTextWriterPtr writer)
193{
194 string token = t.get_current_token();
195 CmdTranslation::p_cmd_translator p = _translations[token];
196 if (!p) {
197 cerr << endl << "Invalid command " << token << endl << endl;
198 return false;
199 }
200
201 try {
202 bool status = p(t, writer);
203 if (!status) {
204 return status;
205 }
206 }
207 catch (BESSyntaxUserError &e) {
208 cerr << e.get_message() << endl;
209 return false;
210 }
211
212 // if this throws an exception then there are no more tokens. Catch it
213 // and ignore the exception. This means we're done.
214 try {
215 token = t.get_next_token();
216 }
217 catch (BESSyntaxUserError &e) {
218 token.clear();
219 }
220
221 if (token.empty()) {
222 // we are done.
223 return true;
224 }
225
226 // more translation to do, so call do_translate again. It will grab the
227 // current token which we just got.
228 return do_translate(t, writer);
229}
230
231bool CmdTranslation::translate_show(BESTokenizer &t, xmlTextWriterPtr writer)
232{
233 CmdTranslation::set_show(true);
234
235 string show_what = t.get_next_token();
236 if (show_what.empty()) {
237 t.parse_error("show command must be followed by target");
238 }
239
240 string new_cmd = "show." + show_what;
241 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
242 if (p) {
243 return p(t, writer);
244 }
245
246 string semi = t.get_next_token();
247 if (semi != ";") {
248 string err = (string) "show " + show_what + " commands must end with a semicolon";
249 t.parse_error(err);
250 }
251 show_what[0] = toupper(show_what[0]);
252 string tag = "show" + show_what;
253
254 // start the show element
255 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
256 if (rc < 0) {
257 cerr << "failed to start " << tag << " element" << endl;
258 return false;
259 }
260
261 // end the show element
262 rc = xmlTextWriterEndElement(writer);
263 if (rc < 0) {
264 cerr << "failed to close " << tag << " element" << endl;
265 return false;
266 }
267
268 return true;
269}
270
271bool CmdTranslation::translate_show_error(BESTokenizer &t, xmlTextWriterPtr writer)
272{
273 string show_what = t.get_current_token();
274 if (show_what.empty() || show_what != "error") {
275 t.parse_error("show command must be error");
276 }
277
278 string etype = t.get_next_token();
279 if (etype == ";") {
280 string err = (string) "show " + show_what + " command must include the error type to show";
281 t.parse_error(err);
282 }
283
284 string semi = t.get_next_token();
285 if (semi != ";") {
286 string err = (string) "show " + show_what + " commands must end with a semicolon";
287 t.parse_error(err);
288 }
289 show_what[0] = toupper(show_what[0]);
290 string tag = "show" + show_what;
291
292 // start the show element
293 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
294 if (rc < 0) {
295 cerr << "failed to start " << tag << " element" << endl;
296 return false;
297 }
298
299 /* Add the error type attribute */
300 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
301 BAD_CAST etype.c_str());
302 if (rc < 0) {
303 cerr << "failed to add the get type attribute" << endl;
304 return false;
305 }
306
307 // end the show element
308 rc = xmlTextWriterEndElement(writer);
309 if (rc < 0) {
310 cerr << "failed to close " << tag << " element" << endl;
311 return false;
312 }
313
314 return true;
315}
316
317bool CmdTranslation::translate_catalog(BESTokenizer &t, xmlTextWriterPtr writer)
318{
319 // show catalog|info [in catalog] [for node]
320 // <showCatalog node="" />
321 string show_what = t.get_current_token();
322 if (show_what.empty() || (show_what != "info" && show_what != "catalog")) {
323 t.parse_error("show command must be info or catalog");
324 }
325
326 show_what[0] = toupper(show_what[0]);
327 string tag = "show" + show_what;
328
329 string token = t.get_next_token();
330 string node;
331 if (token == "for") {
332 node = t.get_next_token();
333 if (node == ";") {
334 t.parse_error("show catalog command expecting node");
335 }
336 node = t.remove_quotes(node);
337 token = t.get_next_token();
338 }
339 if (token != ";") {
340 t.parse_error("show command must be terminated by a semicolon");
341 }
342
343 // start the show element
344 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
345 if (rc < 0) {
346 cerr << "failed to start " << tag << " element" << endl;
347 return false;
348 }
349
350 /* Add the catalog node */
351 if (!node.empty()) {
352 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "node",
353 BAD_CAST node.c_str());
354 if (rc < 0) {
355 cerr << "failed to add the catalog node attribute" << endl;
356 return false;
357 }
358 }
359
360 // end the show element
361 rc = xmlTextWriterEndElement(writer);
362 if (rc < 0) {
363 cerr << "failed to close " << tag << " element" << endl;
364 return false;
365 }
366
367 return true;
368}
369
370bool CmdTranslation::translate_set(BESTokenizer &t, xmlTextWriterPtr writer)
371{
372 string set_what = t.get_next_token();
373 if (set_what.empty()) {
374 t.parse_error("set command must be followed by target");
375 }
376
377 string new_cmd = "set." + set_what;
378 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
379 if (!p) {
380 cerr << "no such command: set " << set_what << endl;
381 return false;
382 }
383
384 return p(t, writer);
385}
386
387bool CmdTranslation::translate_context(BESTokenizer &t, xmlTextWriterPtr writer)
388{
389 // set context blee to blah ;
390 // <setContext name="dap_format">dap2</setContext>
391 string name = t.get_next_token();
392 if (name == ";") {
393 t.parse_error("missing context name");
394 }
395 string to = t.get_next_token();
396 if (to != "to") {
397 t.parse_error("missing word \"to\" in set context");
398 }
399 string value = t.get_next_token();
400 if (value == ";") {
401 t.parse_error("missing context value");
402 }
403 string semi = t.get_next_token();
404 if (semi != ";") {
405 t.parse_error("set context command must end with semicolon");
406 }
407
408 // start the setContext element
409 int rc = xmlTextWriterStartElement(writer, BAD_CAST "setContext");
410 if (rc < 0) {
411 cerr << "failed to start setContext element" << endl;
412 return false;
413 }
414
415 /* Add the context name attribute */
416 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
417 BAD_CAST name.c_str());
418 if (rc < 0) {
419 cerr << "failed to add the context name attribute" << endl;
420 return false;
421 }
422
423 /* Write the value of the context */
424 rc = xmlTextWriterWriteString(writer, BAD_CAST value.c_str());
425 if (rc < 0) {
426 cerr << "failed to write the value of the context" << endl;
427 return false;
428 }
429
430 // end the setContext element
431 rc = xmlTextWriterEndElement(writer);
432 if (rc < 0) {
433 cerr << "failed to close setContext element" << endl;
434 return false;
435 }
436
437 return true;
438}
439
440bool CmdTranslation::translate_container(BESTokenizer &t, xmlTextWriterPtr writer)
441{
442 // set container in space values name,value,type;
443 // <setContainer name="c" space="catalog">/data/fnoc1.nc</setContainer>
444 string token = t.get_next_token();
445 string space;
446 if (token == "in") {
447 space = t.get_next_token();
448 if (space == "values" || space == ";") {
449 t.parse_error("expecting name of container storage");
450 }
451 token = t.get_next_token();
452 }
453 if (token != "values") {
454 t.parse_error("missing values for set container");
455 }
456
457 string name = t.get_next_token();
458 if (name == ";" || name == ",") {
459 t.parse_error("expecting name of the container");
460 }
461
462 token = t.get_next_token();
463 if (token != ",") {
464 t.parse_error("missing comma in set container after name");
465 }
466
467 string value = t.get_next_token();
468 if (value == "," || value == ";") {
469 t.parse_error("expecting location of the container");
470 }
471
472 token = t.get_next_token();
473 string type;
474 if (token == ",") {
475 type = t.get_next_token();
476 if (type == ";") {
477 t.parse_error("expecting container type");
478 }
479 token = t.get_next_token();
480 }
481
482 if (token != ";") {
483 t.parse_error("set container command must end with semicolon");
484 }
485
486 // start the setContainer element
487 int rc = xmlTextWriterStartElement(writer, BAD_CAST "setContainer");
488 if (rc < 0) {
489 cerr << "failed to start setContext element" << endl;
490 return false;
491 }
492
493 /* Add the container name attribute */
494 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
495 BAD_CAST name.c_str());
496 if (rc < 0) {
497 cerr << "failed to add the context name attribute" << endl;
498 return false;
499 }
500
501 if (!space.empty()) {
502 /* Add the container space attribute */
503 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "space",
504 BAD_CAST space.c_str());
505 if (rc < 0) {
506 cerr << "failed to add the container space attribute" << endl;
507 return false;
508 }
509 }
510
511 if (!type.empty()) {
512 /* Add the container space attribute */
513 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
514 BAD_CAST type.c_str());
515 if (rc < 0) {
516 cerr << "failed to add the container type attribute" << endl;
517 return false;
518 }
519 }
520
521 /* Write the value of the container */
522 rc = xmlTextWriterWriteString(writer, BAD_CAST value.c_str());
523 if (rc < 0) {
524 cerr << "failed to write the location of the container" << endl;
525 return false;
526 }
527
528 // end the setContainer element
529 rc = xmlTextWriterEndElement(writer);
530 if (rc < 0) {
531 cerr << "failed to close setContext element" << endl;
532 return false;
533 }
534
535 return true;
536}
537
538bool CmdTranslation::translate_define(BESTokenizer &t, xmlTextWriterPtr writer)
539{
540 // define <def_name> [in <storage_name>] as <container_list> [where // <container_x>.constraint="<constraint>",<container_x>.attributes="<attribute_list>"] // [aggregate by "<aggregation_command>"];
541
542 // <define name="definition_name" space="store_name">
543 // <container name="container_name">
544 // <constraint>legal_constraint</constraint>
545 // <attributes>attribute_list</attributes>
546 // </container>
547 // <aggregate handler="someHandler" cmd="someCommand" />
548 // </define>
549 string name = t.get_next_token();
550 string space;
551 string token = t.get_next_token();
552 if (token == "in") {
553 space = t.get_next_token();
554 token = t.get_next_token();
555 }
556
557 if (token != "as") {
558 t.parse_error("Looking for keyword as in define command");
559 }
560
561 list<string> containers;
562 map<string, string> clist;
563 bool done = false;
564 while (!done) {
565 token = t.get_next_token();
566 containers.push_back(token);
567 clist[token] = token;
568 token = t.get_next_token();
569 if (token != ",") {
570 done = true;
571 }
572 }
573
574 // constraints and attributes
575 map<string, string> constraints;
576 string default_constraint;
577 map<string, string> attrs;
578 if (token == "with") {
579 token = t.get_next_token();
580 unsigned int type;
581 while (token != "aggregate" && token != ";") {
582 // see if we have a default constraint for all containers
583 if (token == "constraint") {
584 default_constraint = t.remove_quotes(t.get_next_token());
585 }
586 else {
587 string c = t.parse_container_name(token, type);
588 if (clist[c] != c) {
589 t.parse_error("constraint container does not exist");
590 }
591 if (type == 1) {
592 // constraint
593 constraints[c] = t.remove_quotes(t.get_next_token());
594 }
595 else if (type == 2) {
596 // attributed
597 attrs[c] = t.remove_quotes(t.get_next_token());
598 }
599 else {
600 t.parse_error("unknown constraint type");
601 }
602 token = t.get_next_token();
603 if (token == ",") {
604 token = t.get_next_token();
605 }
606 }
607 }
608 }
609
610 string agg_handler;
611 string agg_cmd;
612 if (token == "aggregate") {
613 token = t.get_next_token();
614 if (token == "by") {
615 agg_cmd = t.remove_quotes(t.get_next_token());
616 token = t.get_next_token();
617 if (token != "using") {
618 t.parse_error("aggregation expecting keyword \"using\"");
619 }
620 agg_handler = t.get_next_token();
621 }
622 else if (token == "using") {
623 agg_handler = t.get_next_token();
624 token = t.get_next_token();
625 if (token != "by") {
626 t.parse_error("aggregation expecting keyword \"by\"");
627 }
628 agg_cmd = t.remove_quotes(t.get_next_token());
629 }
630 else {
631 t.parse_error("aggregation expecting keyword \"by\" or \"using\"");
632 }
633
634 token = t.get_next_token();
635 }
636
637 if (token != ";") {
638 t.parse_error("define command must end with semicolon");
639 }
640
641 // start the define element
642 int rc = xmlTextWriterStartElement(writer, BAD_CAST "define");
643 if (rc < 0) {
644 cerr << "failed to start setContext element" << endl;
645 return false;
646 }
647
648 /* Add the definition name attribute */
649 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
650 BAD_CAST name.c_str());
651 if (rc < 0) {
652 cerr << "failed to add the context name attribute" << endl;
653 return false;
654 }
655
656 if (!space.empty()) {
657 /* Add the definition space attribute */
658 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "space",
659 BAD_CAST space.c_str());
660 if (rc < 0) {
661 cerr << "failed to add the container space attribute" << endl;
662 return false;
663 }
664 }
665
666 // write the default constraint if we have one
667 if (!default_constraint.empty()) {
668 // start the constraint element
669 int rc = xmlTextWriterStartElement(writer, BAD_CAST "constraint");
670 if (rc < 0) {
671 cerr << "failed to start container constraint element" << endl;
672 return false;
673 }
674
675 /* Write the value of the constraint */
676 rc = xmlTextWriterWriteString(writer, BAD_CAST default_constraint.c_str());
677 if (rc < 0) {
678 cerr << "failed to write constraint for container" << endl;
679 return false;
680 }
681
682 // end the container constraint element
683 rc = xmlTextWriterEndElement(writer);
684 if (rc < 0) {
685 cerr << "failed to close constraint element" << endl;
686 return false;
687 }
688 }
689
690 list<string>::iterator i = containers.begin();
691 list<string>::iterator e = containers.end();
692 for (; i != e; i++) {
693 // start the container element
694 int rc = xmlTextWriterStartElement(writer, BAD_CAST "container");
695 if (rc < 0) {
696 cerr << "failed to start container element" << endl;
697 return false;
698 }
699
700 /* Add the container name attribute */
701 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
702 BAD_CAST (*i).c_str());
703 if (rc < 0) {
704 cerr << "failed to add the context name attribute" << endl;
705 return false;
706 }
707
708 // add constraints and attributes elements here
709 string constraint = constraints[(*i)];
710 if (!constraint.empty()) {
711 // start the constraint element
712 int rc = xmlTextWriterStartElement(writer, BAD_CAST "constraint");
713 if (rc < 0) {
714 cerr << "failed to start container constraint element" << endl;
715 return false;
716 }
717
718 /* Write the value of the constraint */
719 rc = xmlTextWriterWriteString(writer, BAD_CAST constraint.c_str());
720 if (rc < 0) {
721 cerr << "failed to write constraint for container" << endl;
722 return false;
723 }
724
725 // end the container constraint element
726 rc = xmlTextWriterEndElement(writer);
727 if (rc < 0) {
728 cerr << "failed to close constraint element" << endl;
729 return false;
730 }
731 }
732
733 string attr = attrs[(*i)];
734 if (!attr.empty()) {
735 // start the attribute element
736 int rc = xmlTextWriterStartElement(writer, BAD_CAST "attributes");
737 if (rc < 0) {
738 cerr << "failed to start container attributes element" << endl;
739 return false;
740 }
741
742 /* Write the value of the constraint */
743 rc = xmlTextWriterWriteString(writer, BAD_CAST attr.c_str());
744 if (rc < 0) {
745 cerr << "failed to write attributes for container" << endl;
746 return false;
747 }
748
749 // end the container constraint element
750 rc = xmlTextWriterEndElement(writer);
751 if (rc < 0) {
752 cerr << "failed to close attributes element" << endl;
753 return false;
754 }
755 }
756
757 // end the container element
758 rc = xmlTextWriterEndElement(writer);
759 if (rc < 0) {
760 cerr << "failed to close setContext element" << endl;
761 return false;
762 }
763 }
764
765 if (!agg_cmd.empty()) {
766 // start the aggregation element
767 int rc = xmlTextWriterStartElement(writer, BAD_CAST "aggregate");
768 if (rc < 0) {
769 cerr << "failed to start aggregate element" << endl;
770 return false;
771 }
772
773 if (!agg_handler.empty()) {
774 /* Add the aggregation handler attribute */
775 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "handler",
776 BAD_CAST agg_handler.c_str());
777 if (rc < 0) {
778 cerr << "failed to add the context name attribute" << endl;
779 return false;
780 }
781 }
782
783 /* Add the aggregation command attribute */
784 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "cmd",
785 BAD_CAST agg_cmd.c_str());
786 if (rc < 0) {
787 cerr << "failed to add the context name attribute" << endl;
788 return false;
789 }
790
791 // end the aggregation element
792 rc = xmlTextWriterEndElement(writer);
793 if (rc < 0) {
794 cerr << "failed to close setContext element" << endl;
795 return false;
796 }
797 }
798
799 // end the define element
800 rc = xmlTextWriterEndElement(writer);
801 if (rc < 0) {
802 cerr << "failed to close setContext element" << endl;
803 return false;
804 }
805
806 return true;
807}
808
809bool CmdTranslation::translate_delete(BESTokenizer &t, xmlTextWriterPtr writer)
810{
811 // delete container <container_name> [from <storage_name>];
812 // delete containers [from <storage_name>]
813 // delete definition <definition_name> [from <storage_name>];
814 // delete definitions [from <storage_name>];
815
816 // <deleteContainer name="container_name" space="store_name" />
817 // <deleteContainers space="store_name" />
818 // <deleteDefinition name="definition_name" space="store_name" />
819 // <deleteDefinitions space="store_name" />
820
821 string del_what = t.get_next_token();
822 string new_cmd = "delete." + del_what;
823
824 CmdTranslation::p_cmd_translator p = _translations[new_cmd];
825 if (p) {
826 return p(t, writer);
827 }
828
829 bool single = true;
830 if (del_what == "container" || del_what == "definition") {
831 single = true;
832 }
833 else if (del_what == "containers" || del_what == "definitions") {
834 single = false;
835 }
836 else {
837 t.parse_error("unknown delete command");
838 }
839
840 del_what[0] = toupper(del_what[0]);
841 string tag = "delete" + del_what;
842
843 string name;
844 if (single) {
845 name = t.get_next_token();
846 }
847
848 string space;
849 string token = t.get_next_token();
850 if (token == "from") {
851 space = t.get_next_token();
852 token = t.get_next_token();
853 }
854
855 if (token != ";") {
856 t.parse_error("delete command expected to end with semicolon");
857 }
858
859 // start the delete element
860 int rc = xmlTextWriterStartElement(writer, BAD_CAST tag.c_str());
861 if (rc < 0) {
862 cerr << "failed to start aggregate element" << endl;
863 return false;
864 }
865
866 if (!name.empty()) {
867 /* Add the container or definition name attribute */
868 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
869 BAD_CAST name.c_str());
870 if (rc < 0) {
871 cerr << "failed to add the context name attribute" << endl;
872 return false;
873 }
874 }
875
876 if (!space.empty()) {
877 /* Add the container or definition storage space attribute */
878 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "space",
879 BAD_CAST space.c_str());
880 if (rc < 0) {
881 cerr << "failed to add the context name attribute" << endl;
882 return false;
883 }
884 }
885
886 // end the delete element
887 rc = xmlTextWriterEndElement(writer);
888 if (rc < 0) {
889 cerr << "failed to close setContext element" << endl;
890 return false;
891 }
892
893 return true;
894}
895
896bool CmdTranslation::translate_get(BESTokenizer &t, xmlTextWriterPtr writer)
897{
898 // get das|dds|dods|ddx for <definition_name> [return as <return_name>];
899 // <get type="das|dds|dods|ddx" definition="def_name" returnAs="returnAs" />
900 // get html_form for <definition> using <url>;
901 // <get type="das|dds|dods|ddx" definition="def_name" url="url" returnAs="returnAs" />
902 string get_what = t.get_next_token();
903 string token = t.get_next_token();
904 if (token != "for") {
905 t.parse_error("get command expecting keyword \"for\"");
906 }
907
908 string def_name = t.get_next_token();
909 string returnAs;
910 string url;
911 string starting;
912 string bounding;
913 token = t.get_next_token();
914 bool done = false;
915 while (!done) {
916 if (token == "return") {
917 token = t.get_next_token();
918 if (token != "as") {
919 t.parse_error("get command expecting keyword \"as\" for return");
920 }
921 returnAs = t.get_next_token();
922 token = t.get_next_token();
923 }
924 else if (token == "using") {
925 url = t.get_next_token();
926 token = t.get_next_token();
927 }
928 else if (token == "contentStartId") {
929 starting = t.get_next_token();
930 token = t.get_next_token();
931 }
932 else if (token == "mimeBoundary") {
933 bounding = t.get_next_token();
934 token = t.get_next_token();
935 }
936 else if (token == ";") {
937 done = true;
938 }
939 else {
940 t.parse_error("unexpected token in get command");
941 }
942 }
943
944 // start the get element
945 int rc = xmlTextWriterStartElement(writer, BAD_CAST "get");
946 if (rc < 0) {
947 cerr << "failed to start aggregate element" << endl;
948 return false;
949 }
950
951 /* Add the get type attribute */
952 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
953 BAD_CAST get_what.c_str());
954 if (rc < 0) {
955 cerr << "failed to add the get type attribute" << endl;
956 return false;
957 }
958
959 /* Add the get definition attribute */
960 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "definition",
961 BAD_CAST def_name.c_str());
962 if (rc < 0) {
963 cerr << "failed to add the get definition attribute" << endl;
964 return false;
965 }
966
967 if (!url.empty()) {
968 /* Add the get type attribute */
969 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "url",
970 BAD_CAST url.c_str());
971 if (rc < 0) {
972 cerr << "failed to add the url attribute" << endl;
973 return false;
974 }
975 }
976
977 if (!returnAs.empty()) {
978 /* Add the get type attribute */
979 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "returnAs",
980 BAD_CAST returnAs.c_str());
981 if (rc < 0) {
982 cerr << "failed to add the returnAs attribute" << endl;
983 return false;
984 }
985 }
986
987 if (!starting.empty()) {
988 // start the constraint element
989 int rc = xmlTextWriterStartElement(writer, BAD_CAST "contentStartId");
990 if (rc < 0) {
991 cerr << "failed to start contentStartId element" << endl;
992 return false;
993 }
994
995 /* Write the value of the contentStartId */
996 rc = xmlTextWriterWriteString(writer, BAD_CAST starting.c_str());
997 if (rc < 0) {
998 cerr << "failed to write contentStartId for get request" << endl;
999 return false;
1000 }
1001
1002 // end the contentStartId constraint element
1003 rc = xmlTextWriterEndElement(writer);
1004 if (rc < 0) {
1005 cerr << "failed to close constraint element" << endl;
1006 return false;
1007 }
1008 }
1009
1010 if (!bounding.empty()) {
1011 // start the mimeBoundary element
1012 int rc = xmlTextWriterStartElement(writer, BAD_CAST "mimeBoundary");
1013 if (rc < 0) {
1014 cerr << "failed to start mimeBoundary element" << endl;
1015 return false;
1016 }
1017
1018 /* Write the value of the constraint */
1019 rc = xmlTextWriterWriteString(writer, BAD_CAST bounding.c_str());
1020 if (rc < 0) {
1021 cerr << "failed to write mimeBoundary for get request" << endl;
1022 return false;
1023 }
1024
1025 // end the mimeBoundary constraint element
1026 rc = xmlTextWriterEndElement(writer);
1027 if (rc < 0) {
1028 cerr << "failed to close mimeBoundary element" << endl;
1029 return false;
1030 }
1031 }
1032
1033 // end the get element
1034 rc = xmlTextWriterEndElement(writer);
1035 if (rc < 0) {
1036 cerr << "failed to close get element" << endl;
1037 return false;
1038 }
1039
1040 return true;
1041}
1042
1043void CmdTranslation::dump(ostream &strm)
1044{
1045 strm << BESIndent::LMarg << "CmdTranslation::dump" << endl;
1046 BESIndent::Indent();
1047 if (_translations.empty()) {
1048 strm << BESIndent::LMarg << "NO translations registered" << endl;
1049 }
1050 else {
1051 strm << BESIndent::LMarg << "translations registered" << endl;
1052 BESIndent::Indent();
1053 map<string, p_cmd_translator>::iterator i = _translations.begin();
1054 map<string, p_cmd_translator>::iterator e = _translations.end();
1055 for (; i != e; i++) {
1056 strm << BESIndent::LMarg << (*i).first << endl;
1057 }
1058 BESIndent::UnIndent();
1059 }
1060 BESIndent::UnIndent();
1061}
1062
std::string get_message() const
get the error message for this exception
Definition: BESError.h:111
error thrown if there is a user syntax error in the request or any other user error
tokenizer for the BES request command string
Definition: BESTokenizer.h:67
void parse_error(const std::string &s="")
throws an exception giving the tokens up to the point of the problem
Definition: BESTokenizer.cc:65
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
Definition: BESTokenizer.cc:88
std::string & get_next_token()
returns the next token from the token list