CmdTranslation.cc

Go to the documentation of this file.
00001 // CmdTranslation.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #include <iostream>
00034 #include <list>
00035 #include <map>
00036 
00037 using std::cerr ;
00038 using std::cout ;
00039 using std::list ;
00040 using std::map ;
00041 
00042 #include "CmdTranslation.h"
00043 #include "BESTokenizer.h"
00044 #include "BESSyntaxUserError.h"
00045 
00046 #define MY_ENCODING "ISO-8859-1"
00047 
00048 map< string, CmdTranslation::p_cmd_translator > CmdTranslation::_translations ;
00049 bool CmdTranslation::_is_show = false ;
00050 
00051 int
00052 CmdTranslation::initialize(int, char**)
00053 {
00054     _translations["show"] = CmdTranslation::translate_show ;
00055     _translations["show.catalog"] = CmdTranslation::translate_catalog ;
00056     _translations["show.info"] = CmdTranslation::translate_catalog ;
00057     _translations["show.error"] = CmdTranslation::translate_show_error ;
00058     _translations["set"] = CmdTranslation::translate_set ;
00059     _translations["set.context"] = CmdTranslation::translate_context ;
00060     _translations["set.container"] = CmdTranslation::translate_container ;
00061     _translations["define"] = CmdTranslation::translate_define ;
00062     _translations["delete"] = CmdTranslation::translate_delete ;
00063     _translations["get"] = CmdTranslation::translate_get ;
00064     return 0 ;
00065 }
00066 
00067 int
00068 CmdTranslation::terminate(void)
00069 {
00070     return 0 ;
00071 }
00072 
00073 void
00074 CmdTranslation::add_translation( const string &name, p_cmd_translator func )
00075 {
00076     CmdTranslation::_translations[name] = func ;
00077 }
00078 
00079 void
00080 CmdTranslation::remove_translation( const string &name )
00081 {
00082     map<string,p_cmd_translator>::iterator i =
00083         CmdTranslation::_translations.find( name ) ;
00084     if( i != CmdTranslation::_translations.end() )
00085     {
00086         CmdTranslation::_translations.erase( i ) ;
00087     }
00088 }
00089 
00090 string
00091 CmdTranslation::translate( const string &commands )
00092 {
00093     BESTokenizer t ;
00094     try
00095     {
00096         t.tokenize( commands.c_str() ) ;
00097 
00098         string token = t.get_first_token() ;
00099         if( token.empty() )
00100         {
00101             return "" ;
00102         }
00103     }
00104     catch( BESSyntaxUserError &e )
00105     {
00106         cerr << "failed to build tokenizer for translation" << endl ;
00107         cerr << e.get_message() << endl ;
00108         return "" ;
00109     }
00110     
00111     LIBXML_TEST_VERSION;
00112 
00113     int rc;
00114     xmlTextWriterPtr writer = 0 ;
00115     xmlBufferPtr buf = 0 ;
00116     xmlChar *tmp = 0 ;
00117 
00118     /* Create a new XML buffer, to which the XML document will be
00119      * written */
00120     buf = xmlBufferCreate() ;
00121     if( buf == NULL )
00122     {
00123         cerr << "testXmlwriterMemory: Error creating the xml buffer" << endl ;
00124         return "" ;
00125     }
00126 
00127     /* Create a new XmlWriter for memory, with no compression.
00128      * Remark: there is no compression for this kind of xmlTextWriter */
00129     writer = xmlNewTextWriterMemory( buf, 0 ) ;
00130     if( writer == NULL )
00131     {
00132         cerr << "testXmlwriterMemory: Error creating the xml writer" << endl ;
00133         return "" ;
00134     }
00135 
00136     /* Start the document with the xml default for the version,
00137      * encoding ISO 8859-1 and the default for the standalone
00138      * declaration. MY_ENCODING defined at top of this file*/
00139     rc = xmlTextWriterStartDocument( writer, NULL, MY_ENCODING, NULL ) ;
00140     if( rc < 0 )
00141     {
00142         cerr << "testXmlwriterMemory: Error at xmlTextWriterStartDocument"
00143              << endl ;
00144         xmlFreeTextWriter( writer ) ;
00145         return "" ;
00146     }
00147 
00148     /* Start an element named "request". Since thist is the first
00149      * element, this will be the root element of the document. */
00150     rc = xmlTextWriterStartElement( writer, BAD_CAST "request" ) ;
00151     if( rc < 0 )
00152     {
00153         cerr << "testXmlwriterMemory: Error at xmlTextWriterStartElement"
00154              << endl ;
00155         xmlFreeTextWriter( writer ) ;
00156         return "" ;
00157     }
00158 
00159     /* Add the request id attribute */
00160     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "reqID",
00161                                       BAD_CAST "some_unique_value" ) ;
00162     if( rc < 0 )
00163     {
00164         cerr << "failed to add the request id attribute" << endl ;
00165         return "" ;
00166     }
00167 
00168     bool status = do_translate( t, writer ) ;
00169     if( !status )
00170     {
00171         xmlFreeTextWriter( writer ) ;
00172         return "" ;
00173     }
00174 
00175     // this should end the request element
00176     rc = xmlTextWriterEndElement( writer ) ;
00177     if( rc < 0 )
00178     {
00179         cerr << "failed to close request element" << endl ;
00180         xmlFreeTextWriter( writer ) ;
00181         return "" ;
00182     }
00183 
00184     rc = xmlTextWriterEndDocument( writer ) ;
00185     if( rc < 0 )
00186     {
00187         cerr << "failed to end the document" << endl ;
00188         return "" ;
00189     }
00190 
00191     xmlFreeTextWriter(writer);
00192 
00193     // get the xml document as a string and return
00194     string doc ;
00195     if( !buf->content )
00196     {
00197         cerr << "failed to retrieve document as string" << endl ;
00198     }
00199     else
00200     {
00201         doc = (char *)buf->content ;
00202     }
00203 
00204     xmlBufferFree( buf ) ;
00205 
00206     xmlCleanupParser();
00207 
00208     return doc ;
00209 }
00210 
00211 bool
00212 CmdTranslation::do_translate( BESTokenizer &t, xmlTextWriterPtr writer )
00213 {
00214     string token = t.get_current_token() ;
00215     CmdTranslation::p_cmd_translator p = _translations[token] ;
00216     if( !p )
00217     {
00218         cerr << endl << "Invalid command " << token << endl << endl ;
00219         return false ;
00220     }
00221 
00222     try
00223     {
00224         bool status = p( t, writer ) ;
00225         if( !status )
00226         {
00227             return status ;
00228         }
00229     }
00230     catch( BESSyntaxUserError &e )
00231     {
00232         cerr << e.get_message() << endl ;
00233         return false ;
00234     }
00235 
00236     // if this throws an exception then there are no more tokens. Catch it
00237     // and ignore the exception. This means we're done.
00238     try
00239     {
00240         token = t.get_next_token() ;
00241     }
00242     catch( BESSyntaxUserError &e )
00243     {
00244         token.clear() ;
00245     }
00246 
00247     if( token.empty() )
00248     {
00249         // we are done.
00250         return true ;
00251     }
00252 
00253     // more translation to do, so call do_translate again. It will grab the
00254     // current token which we just got.
00255     return do_translate( t, writer ) ;
00256 }
00257 
00258 bool
00259 CmdTranslation::translate_show( BESTokenizer &t, xmlTextWriterPtr writer )
00260 {
00261     CmdTranslation::set_show( true ) ;
00262 
00263     string show_what = t.get_next_token() ;
00264     if( show_what.empty() )
00265     {
00266         t.parse_error( "show command must be followed by target" ) ;
00267     }
00268 
00269     string new_cmd = "show." + show_what ;
00270     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00271     if( p )
00272     {
00273         return p( t, writer ) ;
00274     }
00275 
00276     string semi = t.get_next_token() ;
00277     if( semi != ";" )
00278     {
00279         string err = (string)"show " + show_what
00280                      + " commands must end with a semicolon" ;
00281         t.parse_error( err ) ;
00282     }
00283     show_what[0] = toupper( show_what[0] ) ;
00284     string tag = "show" + show_what ;
00285 
00286     // start the show element
00287     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00288     if( rc < 0 )
00289     {
00290         cerr << "failed to start " << tag << " element" << endl ;
00291         return false ;
00292     }
00293 
00294     // end the show element
00295     rc = xmlTextWriterEndElement( writer ) ;
00296     if( rc < 0 )
00297     {
00298         cerr << "failed to close " << tag << " element" << endl ;
00299         return false ;
00300     }
00301 
00302     return true ;
00303 }
00304 
00305 bool
00306 CmdTranslation::translate_show_error( BESTokenizer &t, xmlTextWriterPtr writer)
00307 {
00308     string show_what = t.get_current_token() ;
00309     if( show_what.empty() || show_what != "error" )
00310     {
00311         t.parse_error( "show command must be error" ) ;
00312     }
00313 
00314     string etype = t.get_next_token() ;
00315     if( etype == ";" )
00316     {
00317         string err = (string)"show " + show_what
00318                      + " command must inlude the error type to show" ;
00319         t.parse_error( err ) ;
00320     }
00321 
00322     string semi = t.get_next_token() ;
00323     if( semi != ";" )
00324     {
00325         string err = (string)"show " + show_what
00326                      + " commands must end with a semicolon" ;
00327         t.parse_error( err ) ;
00328     }
00329     show_what[0] = toupper( show_what[0] ) ;
00330     string tag = "show" + show_what ;
00331 
00332     // start the show element
00333     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00334     if( rc < 0 )
00335     {
00336         cerr << "failed to start " << tag << " element" << endl ;
00337         return false ;
00338     }
00339 
00340     /* Add the error type attribute */
00341     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
00342                                       BAD_CAST etype.c_str() ) ;
00343     if( rc < 0 )
00344     {
00345         cerr << "failed to add the get type attribute" << endl ;
00346         return "" ;
00347     }
00348 
00349     // end the show element
00350     rc = xmlTextWriterEndElement( writer ) ;
00351     if( rc < 0 )
00352     {
00353         cerr << "failed to close " << tag << " element" << endl ;
00354         return false ;
00355     }
00356 
00357     return true ;
00358 }
00359 
00360 bool
00361 CmdTranslation::translate_catalog( BESTokenizer &t, xmlTextWriterPtr writer )
00362 {
00363     // show catalog|info [for node]
00364     // <showCatalog node="" />
00365     string show_what = t.get_current_token() ;
00366     if( show_what.empty() || ( show_what != "info" && show_what != "catalog" ) )
00367     {
00368         t.parse_error( "show command must be info or catalog" ) ;
00369     }
00370 
00371     show_what[0] = toupper( show_what[0] ) ;
00372     string tag = "show" + show_what ;
00373 
00374     string token = t.get_next_token() ;
00375     string node ;
00376     if( token == "for" )
00377     {
00378         node = t.get_next_token() ;
00379         if( node == ";" )
00380         {
00381             t.parse_error( "show catalog command expecting node" ) ;
00382         }
00383         node = t.remove_quotes( node ) ;
00384         token = t.get_next_token() ;
00385     }
00386     if( token != ";" )
00387     {
00388         t.parse_error( "show command must be terminated by a semicolon" ) ;
00389     }
00390 
00391     // start the show element
00392     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00393     if( rc < 0 )
00394     {
00395         cerr << "failed to start " << tag << " element" << endl ;
00396         return false ;
00397     }
00398 
00399     /* Add the catalog node */
00400     if( !node.empty() )
00401     {
00402         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "node",
00403                                           BAD_CAST node.c_str() ) ;
00404         if( rc < 0 )
00405         {
00406             cerr << "failed to add the catalog node attribute" << endl ;
00407             return "" ;
00408         }
00409     }
00410 
00411     // end the show element
00412     rc = xmlTextWriterEndElement( writer ) ;
00413     if( rc < 0 )
00414     {
00415         cerr << "failed to close " << tag << " element" << endl ;
00416         return false ;
00417     }
00418 
00419     return true ;
00420 }
00421 
00422 bool
00423 CmdTranslation::translate_set( BESTokenizer &t,
00424                                xmlTextWriterPtr writer )
00425 {
00426     string set_what = t.get_next_token() ;
00427     if( set_what.empty() )
00428     {
00429         t.parse_error( "set command must be followed by target" ) ;
00430     }
00431 
00432     string new_cmd = "set." + set_what ;
00433     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00434     if( !p )
00435     {
00436         cerr << "no such command: set " << set_what << endl ;
00437         return false ;
00438     }
00439 
00440     return p( t, writer ) ;
00441 }
00442 
00443 bool
00444 CmdTranslation::translate_context( BESTokenizer &t,
00445                                    xmlTextWriterPtr writer )
00446 {
00447     // set context blee to blah ;
00448     // <setContext name="dap_format">dap2</setContext>
00449     string name = t.get_next_token() ;
00450     if( name == ";" )
00451     {
00452         t.parse_error( "missing context name" ) ;
00453     }
00454     string to = t.get_next_token() ;
00455     if( to != "to" )
00456     {
00457         t.parse_error( "missing word \"to\" in set context" ) ;
00458     }
00459     string value = t.get_next_token() ;
00460     if( value == ";" )
00461     {
00462         t.parse_error( "missing context value" ) ;
00463     }
00464     string semi = t.get_next_token() ;
00465     if( semi != ";" )
00466     {
00467         t.parse_error( "set context command must end with semicolon" ) ;
00468     }
00469 
00470     // start the setContext element
00471     int rc = xmlTextWriterStartElement( writer, BAD_CAST "setContext" ) ;
00472     if( rc < 0 )
00473     {
00474         cerr << "failed to start setContext element" << endl ;
00475         return false ;
00476     }
00477 
00478     /* Add the context name attribute */
00479     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00480                                       BAD_CAST name.c_str() ) ;
00481     if( rc < 0 )
00482     {
00483         cerr << "failed to add the context name attribute" << endl ;
00484         return "" ;
00485     }
00486 
00487     /* Write the value of the context */
00488     rc = xmlTextWriterWriteString( writer, BAD_CAST value.c_str() ) ;
00489     if( rc < 0 )
00490     {
00491         cerr << "failed to write the value of the context" << endl ;
00492         return "" ;
00493     }
00494 
00495     // end the setContext element
00496     rc = xmlTextWriterEndElement( writer ) ;
00497     if( rc < 0 )
00498     {
00499         cerr << "failed to close setContext element" << endl ;
00500         return false ;
00501     }
00502 
00503     return true ;
00504 }
00505 
00506 bool
00507 CmdTranslation::translate_container( BESTokenizer &t,
00508                                      xmlTextWriterPtr writer )
00509 {
00510     // set container in space values name,value,type;
00511     // <setContainer name="c" space="catalog">/data/fnoc1.nc</setContainer>
00512     string token = t.get_next_token() ;
00513     string space ;
00514     if( token == "in" )
00515     {
00516         space = t.get_next_token() ;
00517         if( space == "values" || space == ";" )
00518         {
00519             t.parse_error( "expecting name of container storage" ) ;
00520         }
00521         token = t.get_next_token() ;
00522     }
00523     if( token != "values" )
00524     {
00525         t.parse_error( "missing values for set container" ) ;
00526     }
00527 
00528     string name = t.get_next_token() ;
00529     if( name == ";" || name == "," )
00530     {
00531         t.parse_error( "expecting name of the container" ) ;
00532     }
00533 
00534     token = t.get_next_token() ;
00535     if( token != "," )
00536     {
00537         t.parse_error( "missing comma in set container after name" ) ;
00538     }
00539 
00540     string value = t.get_next_token() ;
00541     if( value == "," || value == ";" )
00542     {
00543         t.parse_error( "expecting location of the container" ) ;
00544     }
00545 
00546     token = t.get_next_token() ;
00547     string type ;
00548     if( token == "," )
00549     {
00550         type = t.get_next_token() ;
00551         if( type == ";" )
00552         {
00553             t.parse_error( "expecting container type" ) ;
00554         }
00555         token = t.get_next_token() ;
00556     }
00557 
00558     if( token != ";" )
00559     {
00560         t.parse_error( "set container command must end with semicolon" ) ;
00561     }
00562 
00563     // start the setContainer element
00564     int rc = xmlTextWriterStartElement( writer, BAD_CAST "setContainer" ) ;
00565     if( rc < 0 )
00566     {
00567         cerr << "failed to start setContext element" << endl ;
00568         return false ;
00569     }
00570 
00571     /* Add the container name attribute */
00572     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00573                                       BAD_CAST name.c_str() ) ;
00574     if( rc < 0 )
00575     {
00576         cerr << "failed to add the context name attribute" << endl ;
00577         return "" ;
00578     }
00579 
00580     if( !space.empty() )
00581     {
00582         /* Add the container space attribute */
00583         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00584                                           BAD_CAST space.c_str() ) ;
00585         if( rc < 0 )
00586         {
00587             cerr << "failed to add the container space attribute" << endl ;
00588             return "" ;
00589         }
00590     }
00591 
00592     if( !type.empty() )
00593     {
00594         /* Add the container space attribute */
00595         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
00596                                           BAD_CAST type.c_str() ) ;
00597         if( rc < 0 )
00598         {
00599             cerr << "failed to add the container type attribute" << endl ;
00600             return "" ;
00601         }
00602     }
00603 
00604     /* Write the value of the container */
00605     rc = xmlTextWriterWriteString( writer, BAD_CAST value.c_str() ) ;
00606     if( rc < 0 )
00607     {
00608         cerr << "failed to write the location of the container" << endl ;
00609         return "" ;
00610     }
00611 
00612     // end the setContainer element
00613     rc = xmlTextWriterEndElement( writer ) ;
00614     if( rc < 0 )
00615     {
00616         cerr << "failed to close setContext element" << endl ;
00617         return false ;
00618     }
00619 
00620     return true ;
00621 }
00622 
00623 bool
00624 CmdTranslation::translate_define( BESTokenizer &t,
00625                                   xmlTextWriterPtr writer )
00626 {
00627     // define <def_name> [in <storage_name>] as <container_list> [where // <container_x>.constraint="<constraint>",<container_x>.attributes="<attribute_list>"] // [aggregate by "<aggregation_command>"];
00628 
00629     // <define name="definition_name" space="store_name">
00630     //  <container name="container_name">
00631     //      <constraint>legal_constraint</constraint>
00632     //      <attributes>attribute_list</attributes>
00633     //  </container>
00634     //  <aggregate handler="someHandler" cmd="someCommand" />
00635     // </define>
00636     string name = t.get_next_token() ;
00637     string space ;
00638     string token = t.get_next_token() ;
00639     if( token == "in" )
00640     {
00641         space = t.get_next_token() ;
00642         token = t.get_next_token() ;
00643     }
00644 
00645     if( token != "as" )
00646     {
00647         t.parse_error( "Looking for keyword as in define command" ) ;
00648     }
00649 
00650     list<string> containers ;
00651     map<string,string> clist ;
00652     bool done = false ;
00653     while( !done )
00654     {
00655         token = t.get_next_token() ;
00656         containers.push_back( token ) ;
00657         clist[token] = token ;
00658         token = t.get_next_token() ;
00659         if( token != "," )
00660         {
00661             done = true ;
00662         }
00663     }
00664 
00665     // constraints and attributes
00666     map<string,string> constraints ;
00667     string default_constraint ;
00668     map<string,string> attrs ;
00669     if( token == "with" )
00670     {
00671         token = t.get_next_token() ;
00672         unsigned int type ;
00673         while( token != "aggregate" && token != ";" )
00674         {
00675             // see if we have a default constraint for all containers
00676             if( token == "constraint" )
00677             {
00678                 default_constraint = t.remove_quotes( t.get_next_token() ) ;
00679             }
00680             else
00681             {
00682                 string c = t.parse_container_name( token, type ) ;
00683                 if( clist[c] != c )
00684                 {
00685                     t.parse_error( "contstraint container does not exist" ) ;
00686                 }
00687                 if( type == 1 )
00688                 {
00689                     // constraint
00690                     constraints[c] = t.remove_quotes( t.get_next_token() ) ;
00691                 }
00692                 else if( type == 2 )
00693                 {
00694                     // attributed
00695                     attrs[c] = t.remove_quotes( t.get_next_token() ) ;
00696                 }
00697                 else
00698                 {
00699                     t.parse_error( "unknown constraint type" ) ;
00700                 }
00701                 token = t.get_next_token() ;
00702                 if( token == "," )
00703                 {
00704                     token = t.get_next_token() ;
00705                 }
00706             }
00707         }
00708     }
00709 
00710     string agg_handler ;
00711     string agg_cmd ;
00712     if( token == "aggregate" )
00713     {
00714         token = t.get_next_token() ;
00715         if( token == "by" )
00716         {
00717             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00718             token = t.get_next_token() ;
00719             if( token != "using" )
00720             {
00721                 t.parse_error( "aggregation expecting keyword \"using\"");
00722             }
00723             agg_handler = t.get_next_token() ;
00724         }
00725         else if( token == "using" )
00726         {
00727             agg_handler = t.get_next_token() ;
00728             token = t.get_next_token() ;
00729             if( token != "by" )
00730             {
00731                 t.parse_error( "aggregation expecting keyword \"by\"");
00732             }
00733             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00734         }
00735         else
00736         {
00737             t.parse_error( "aggregation expecting keyword \"by\" or \"using\"");
00738         }
00739 
00740         token = t.get_next_token() ;
00741     }
00742 
00743     if( token != ";" )
00744     {
00745         t.parse_error( "define command must end with semicolon" ) ;
00746     }
00747 
00748     // start the define element
00749     int rc = xmlTextWriterStartElement( writer, BAD_CAST "define" ) ;
00750     if( rc < 0 )
00751     {
00752         cerr << "failed to start setContext element" << endl ;
00753         return false ;
00754     }
00755 
00756     /* Add the definition name attribute */
00757     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00758                                       BAD_CAST name.c_str() ) ;
00759     if( rc < 0 )
00760     {
00761         cerr << "failed to add the context name attribute" << endl ;
00762         return "" ;
00763     }
00764 
00765     if( !space.empty() )
00766     {
00767         /* Add the definition space attribute */
00768         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00769                                           BAD_CAST space.c_str() ) ;
00770         if( rc < 0 )
00771         {
00772             cerr << "failed to add the container space attribute" << endl ;
00773             return "" ;
00774         }
00775     }
00776 
00777     // write the default constraint if we have one
00778     if( !default_constraint.empty() )
00779     {
00780         // start the constraint element
00781         int rc = xmlTextWriterStartElement( writer, BAD_CAST "constraint" );
00782         if( rc < 0 )
00783         {
00784             cerr << "failed to start container constraint element" << endl ;
00785             return false ;
00786         }
00787 
00788         /* Write the value of the constraint */
00789         rc = xmlTextWriterWriteString( writer, BAD_CAST default_constraint.c_str());
00790         if( rc < 0 )
00791         {
00792             cerr << "failed to write constraint for container" << endl ;
00793             return "" ;
00794         }
00795 
00796         // end the container constraint element
00797         rc = xmlTextWriterEndElement( writer ) ;
00798         if( rc < 0 )
00799         {
00800             cerr << "failed to close constraint element" << endl ;
00801             return false ;
00802         }
00803     }
00804 
00805     list<string>::iterator i = containers.begin() ;
00806     list<string>::iterator e = containers.end() ;
00807     for( ; i != e; i++ )
00808     {
00809         // start the container element
00810         int rc = xmlTextWriterStartElement( writer, BAD_CAST "container" ) ;
00811         if( rc < 0 )
00812         {
00813             cerr << "failed to start container element" << endl ;
00814             return false ;
00815         }
00816 
00817         /* Add the container name attribute */
00818         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00819                                           BAD_CAST (*i).c_str() ) ;
00820         if( rc < 0 )
00821         {
00822             cerr << "failed to add the context name attribute" << endl ;
00823             return "" ;
00824         }
00825 
00826         // add constraints and attributes elements here
00827         string constraint = constraints[(*i)] ;
00828         if( !constraint.empty() )
00829         {
00830             // start the constraint element
00831             int rc = xmlTextWriterStartElement( writer, BAD_CAST "constraint" );
00832             if( rc < 0 )
00833             {
00834                 cerr << "failed to start container constraint element" << endl ;
00835                 return false ;
00836             }
00837 
00838             /* Write the value of the constraint */
00839             rc = xmlTextWriterWriteString( writer, BAD_CAST constraint.c_str());
00840             if( rc < 0 )
00841             {
00842                 cerr << "failed to write constraint for container" << endl ;
00843                 return "" ;
00844             }
00845 
00846             // end the container constraint element
00847             rc = xmlTextWriterEndElement( writer ) ;
00848             if( rc < 0 )
00849             {
00850                 cerr << "failed to close constraint element" << endl ;
00851                 return false ;
00852             }
00853         }
00854 
00855         string attr = attrs[(*i)] ;
00856         if( !attr.empty() )
00857         {
00858             // start the attribute element
00859             int rc = xmlTextWriterStartElement( writer, BAD_CAST "attributes" );
00860             if( rc < 0 )
00861             {
00862                 cerr << "failed to start container attributes element" << endl ;
00863                 return false ;
00864             }
00865 
00866             /* Write the value of the constraint */
00867             rc = xmlTextWriterWriteString( writer, BAD_CAST attr.c_str());
00868             if( rc < 0 )
00869             {
00870                 cerr << "failed to write attributes for container" << endl ;
00871                 return "" ;
00872             }
00873 
00874             // end the container constraint element
00875             rc = xmlTextWriterEndElement( writer ) ;
00876             if( rc < 0 )
00877             {
00878                 cerr << "failed to close attributes element" << endl ;
00879                 return false ;
00880             }
00881         }
00882 
00883         // end the container element
00884         rc = xmlTextWriterEndElement( writer ) ;
00885         if( rc < 0 )
00886         {
00887             cerr << "failed to close setContext element" << endl ;
00888             return false ;
00889         }
00890     }
00891 
00892     if( !agg_cmd.empty() )
00893     {
00894         // start the aggregation element
00895         int rc = xmlTextWriterStartElement( writer, BAD_CAST "aggregate" ) ;
00896         if( rc < 0 )
00897         {
00898             cerr << "failed to start aggregate element" << endl ;
00899             return false ;
00900         }
00901 
00902         if( !agg_handler.empty() )
00903         {
00904             /* Add the aggregation handler attribute */
00905             rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "handler",
00906                                               BAD_CAST agg_handler.c_str() ) ;
00907             if( rc < 0 )
00908             {
00909                 cerr << "failed to add the context name attribute" << endl ;
00910                 return "" ;
00911             }
00912         }
00913 
00914         /* Add the aggregation command attribute */
00915         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "cmd",
00916                                           BAD_CAST agg_cmd.c_str() ) ;
00917         if( rc < 0 )
00918         {
00919             cerr << "failed to add the context name attribute" << endl ;
00920             return "" ;
00921         }
00922 
00923         // end the aggregation element
00924         rc = xmlTextWriterEndElement( writer ) ;
00925         if( rc < 0 )
00926         {
00927             cerr << "failed to close setContext element" << endl ;
00928             return false ;
00929         }
00930     }
00931 
00932     // end the define element
00933     rc = xmlTextWriterEndElement( writer ) ;
00934     if( rc < 0 )
00935     {
00936         cerr << "failed to close setContext element" << endl ;
00937         return false ;
00938     }
00939 
00940     return true ;
00941 }
00942 
00943 bool
00944 CmdTranslation::translate_delete( BESTokenizer &t,
00945                                   xmlTextWriterPtr writer )
00946 {
00947     // delete container <container_name> [from <storage_name>];
00948     // delete containers [from <storage_name>]
00949     // delete definition <definition_name> [from <storage_name>];
00950     // delete definitions [from <storage_name>];
00951 
00952     // <deleteContainer name="container_name" space="store_name" />
00953     // <deleteContainers space="store_name" />
00954     // <deleteDefinition name="definition_name" space="store_name" />
00955     // <deleteDefinitions space="store_name" />
00956 
00957     string del_what = t.get_next_token() ;
00958     string new_cmd = "delete." + del_what ;
00959 
00960     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00961     if( p )
00962     {
00963         return p( t, writer ) ;
00964     }
00965 
00966     bool single = true ;
00967     if( del_what == "container" || del_what == "definition" )
00968     {
00969         single = true ;
00970     }
00971     else if( del_what == "containers" || del_what == "definitions" )
00972     {
00973         single = false ;
00974     }
00975     else
00976     {
00977         t.parse_error( "unknown delete command" ) ;
00978     }
00979 
00980     del_what[0] = toupper( del_what[0] ) ;
00981     string tag = "delete" + del_what ;
00982 
00983     string name ;
00984     if( single )
00985     {
00986         name = t.get_next_token() ;
00987     }
00988 
00989     string space ;
00990     string token = t.get_next_token() ;
00991     if( token == "from" )
00992     {
00993         space = t.get_next_token() ;
00994         token = t.get_next_token() ;
00995     }
00996     
00997     if( token != ";" )
00998     {
00999         t.parse_error( "delete command expected to end with semicolon" ) ;
01000     }
01001 
01002     // start the delete element
01003     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
01004     if( rc < 0 )
01005     {
01006         cerr << "failed to start aggregate element" << endl ;
01007         return false ;
01008     }
01009 
01010     if( !name.empty() )
01011     {
01012         /* Add the container or definition name attribute */
01013         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
01014                                           BAD_CAST name.c_str() ) ;
01015         if( rc < 0 )
01016         {
01017             cerr << "failed to add the context name attribute" << endl ;
01018             return "" ;
01019         }
01020     }
01021 
01022     if( !space.empty() )
01023     {
01024         /* Add the container or definition storage space attribute */
01025         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
01026                                           BAD_CAST space.c_str() ) ;
01027         if( rc < 0 )
01028         {
01029             cerr << "failed to add the context name attribute" << endl ;
01030             return "" ;
01031         }
01032     }
01033 
01034     // end the delete element
01035     rc = xmlTextWriterEndElement( writer ) ;
01036     if( rc < 0 )
01037     {
01038         cerr << "failed to close setContext element" << endl ;
01039         return false ;
01040     }
01041 
01042     return true ;
01043 }
01044 
01045 bool
01046 CmdTranslation::translate_get( BESTokenizer &t,
01047                                xmlTextWriterPtr writer )
01048 {
01049     // get das|dds|dods|ddx for <definition_name> [return as <return_name>];
01050     // <get type="das|dds|dods|ddx" definition="def_name" returnAs="returnAs" />
01051     // get html_form for <definition> using <url>;
01052     // <get type="das|dds|dods|ddx" definition="def_name" url="url" returnAs="returnAs" />
01053     string get_what = t.get_next_token() ;
01054     string token = t.get_next_token() ;
01055     if( token != "for" )
01056     {
01057         t.parse_error( "get command expecting keyword \"for\"" ) ;
01058     }
01059 
01060     string def_name = t.get_next_token() ;
01061     string returnAs ;
01062     string url ;
01063     string starting ;
01064     string bounding ;
01065     token = t.get_next_token() ;
01066     bool done = false ;
01067     while( !done )
01068     {
01069         if( token == "return" )
01070         {
01071             token = t.get_next_token() ;
01072             if( token != "as" )
01073             {
01074                 t.parse_error( "get command expecting keyword \"as\" for return" ) ;
01075             }
01076             returnAs = t.get_next_token() ;
01077             token = t.get_next_token() ;
01078         }
01079         else if( token == "using" )
01080         {
01081             url = t.get_next_token() ;
01082             token = t.get_next_token() ;
01083         }
01084         else if( token == "contentStartId" )
01085         {
01086             starting = t.get_next_token() ;
01087             token = t.get_next_token() ;
01088         }
01089         else if( token == "mimeBoundary" )
01090         {
01091             bounding = t.get_next_token() ;
01092             token = t.get_next_token() ;
01093         }
01094         else if( token == ";" )
01095         {
01096             done = true ;
01097         }
01098         else
01099         {
01100             t.parse_error( "unexpected token in get command" ) ;
01101         }
01102     }
01103 
01104     // start the get element
01105     int rc = xmlTextWriterStartElement( writer, BAD_CAST "get" ) ;
01106     if( rc < 0 )
01107     {
01108         cerr << "failed to start aggregate element" << endl ;
01109         return false ;
01110     }
01111 
01112     /* Add the get type attribute */
01113     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
01114                                       BAD_CAST get_what.c_str() ) ;
01115     if( rc < 0 )
01116     {
01117         cerr << "failed to add the get type attribute" << endl ;
01118         return "" ;
01119     }
01120 
01121     /* Add the get definition attribute */
01122     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "definition",
01123                                       BAD_CAST def_name.c_str() ) ;
01124     if( rc < 0 )
01125     {
01126         cerr << "failed to add the get definition attribute" << endl ;
01127         return "" ;
01128     }
01129 
01130     if( !url.empty() )
01131     {
01132         /* Add the get type attribute */
01133         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "url",
01134                                           BAD_CAST url.c_str() ) ;
01135         if( rc < 0 )
01136         {
01137             cerr << "failed to add the url attribute" << endl ;
01138             return "" ;
01139         }
01140     }
01141 
01142     if( !returnAs.empty() )
01143     {
01144         /* Add the get type attribute */
01145         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "returnAs",
01146                                           BAD_CAST returnAs.c_str() ) ;
01147         if( rc < 0 )
01148         {
01149             cerr << "failed to add the returnAs attribute" << endl ;
01150             return "" ;
01151         }
01152     }
01153 
01154     if( !starting.empty() )
01155     {
01156         // start the constraint element
01157         int rc = xmlTextWriterStartElement( writer, BAD_CAST "contentStartId" );
01158         if( rc < 0 )
01159         {
01160             cerr << "failed to start contentStartId element" << endl ;
01161             return false ;
01162         }
01163 
01164         /* Write the value of the contentStartId */
01165         rc = xmlTextWriterWriteString( writer, BAD_CAST starting.c_str());
01166         if( rc < 0 )
01167         {
01168             cerr << "failed to write contentStartId for get request" << endl ;
01169             return "" ;
01170         }
01171 
01172         // end the contentStartId constraint element
01173         rc = xmlTextWriterEndElement( writer ) ;
01174         if( rc < 0 )
01175         {
01176             cerr << "failed to close constraint element" << endl ;
01177             return false ;
01178         }
01179     }
01180 
01181     if( !bounding.empty() )
01182     {
01183         // start the mimeBoundary element
01184         int rc = xmlTextWriterStartElement( writer, BAD_CAST "mimeBoundary" );
01185         if( rc < 0 )
01186         {
01187             cerr << "failed to start mimeBoundary element" << endl ;
01188             return false ;
01189         }
01190 
01191         /* Write the value of the constraint */
01192         rc = xmlTextWriterWriteString( writer, BAD_CAST bounding.c_str());
01193         if( rc < 0 )
01194         {
01195             cerr << "failed to write mimeBoundary for get request" << endl ;
01196             return "" ;
01197         }
01198 
01199         // end the mimeBoundary constraint element
01200         rc = xmlTextWriterEndElement( writer ) ;
01201         if( rc < 0 )
01202         {
01203             cerr << "failed to close mimeBoundary element" << endl ;
01204             return false ;
01205         }
01206     }
01207 
01208     // end the get element
01209     rc = xmlTextWriterEndElement( writer ) ;
01210     if( rc < 0 )
01211     {
01212         cerr << "failed to close get element" << endl ;
01213         return false ;
01214     }
01215 
01216     return true ;
01217 }
01218 
01219 void
01220 CmdTranslation::dump( ostream &strm )
01221 {
01222     strm << BESIndent::LMarg << "CmdTranslation::dump" << endl ;
01223     BESIndent::Indent() ;
01224     if( _translations.empty() )
01225     {
01226         strm << BESIndent::LMarg << "NO translations registered" << endl ;
01227     }
01228     else
01229     {
01230         strm << BESIndent::LMarg << "translations registered" << endl ;
01231         BESIndent::Indent() ;
01232         map<string,p_cmd_translator>::iterator i = _translations.begin() ;
01233         map<string,p_cmd_translator>::iterator e = _translations.end() ;
01234         for( ; i != e; i++ )
01235         {
01236             strm << BESIndent::LMarg << (*i).first << endl ;
01237         }
01238         BESIndent::UnIndent() ;
01239     }
01240     BESIndent::UnIndent() ;
01241 }
01242 
Generated by  doxygen 1.6.2-20100208