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     map<string,string> attrs ;
00668     if( token == "with" )
00669     {
00670         token = t.get_next_token() ;
00671         unsigned int type ;
00672         while( token != "aggregate" && token != ";" )
00673         {
00674             string c = t.parse_container_name( token, type ) ;
00675             if( clist[c] != c )
00676             {
00677                 t.parse_error( "contstraint container does not exist" ) ;
00678             }
00679             if( type == 1 )
00680             {
00681                 // constraint
00682                 constraints[c] = t.remove_quotes( t.get_next_token() ) ;
00683             }
00684             else if( type == 2 )
00685             {
00686                 // attributed
00687                 attrs[c] = t.remove_quotes( t.get_next_token() ) ;
00688             }
00689             else
00690             {
00691                 t.parse_error( "unknown constraint type" ) ;
00692             }
00693             token = t.get_next_token() ;
00694             if( token == "," )
00695             {
00696                 token = t.get_next_token() ;
00697             }
00698         }
00699     }
00700 
00701     string agg_handler ;
00702     string agg_cmd ;
00703     if( token == "aggregate" )
00704     {
00705         token = t.get_next_token() ;
00706         if( token == "by" )
00707         {
00708             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00709             token = t.get_next_token() ;
00710             if( token != "using" )
00711             {
00712                 t.parse_error( "aggregation expecting keyword \"using\"");
00713             }
00714             agg_handler = t.get_next_token() ;
00715         }
00716         else if( token == "using" )
00717         {
00718             agg_handler = t.get_next_token() ;
00719             token = t.get_next_token() ;
00720             if( token != "by" )
00721             {
00722                 t.parse_error( "aggregation expecting keyword \"by\"");
00723             }
00724             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00725         }
00726         else
00727         {
00728             t.parse_error( "aggregation expecting keyword \"by\" or \"using\"");
00729         }
00730 
00731         token = t.get_next_token() ;
00732     }
00733 
00734     if( token != ";" )
00735     {
00736         t.parse_error( "define command must end with semicolon" ) ;
00737     }
00738 
00739     // start the define element
00740     int rc = xmlTextWriterStartElement( writer, BAD_CAST "define" ) ;
00741     if( rc < 0 )
00742     {
00743         cerr << "failed to start setContext element" << endl ;
00744         return false ;
00745     }
00746 
00747     /* Add the definition name attribute */
00748     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00749                                       BAD_CAST name.c_str() ) ;
00750     if( rc < 0 )
00751     {
00752         cerr << "failed to add the context name attribute" << endl ;
00753         return "" ;
00754     }
00755 
00756     if( !space.empty() )
00757     {
00758         /* Add the definition space attribute */
00759         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00760                                           BAD_CAST space.c_str() ) ;
00761         if( rc < 0 )
00762         {
00763             cerr << "failed to add the container space attribute" << endl ;
00764             return "" ;
00765         }
00766     }
00767 
00768     list<string>::iterator i = containers.begin() ;
00769     list<string>::iterator e = containers.end() ;
00770     for( ; i != e; i++ )
00771     {
00772         // start the container element
00773         int rc = xmlTextWriterStartElement( writer, BAD_CAST "container" ) ;
00774         if( rc < 0 )
00775         {
00776             cerr << "failed to start container element" << endl ;
00777             return false ;
00778         }
00779 
00780         /* Add the container name attribute */
00781         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00782                                           BAD_CAST (*i).c_str() ) ;
00783         if( rc < 0 )
00784         {
00785             cerr << "failed to add the context name attribute" << endl ;
00786             return "" ;
00787         }
00788 
00789         // add constraints and attributes elements here
00790         string constraint = constraints[(*i)] ;
00791         if( !constraint.empty() )
00792         {
00793             // start the constraint element
00794             int rc = xmlTextWriterStartElement( writer, BAD_CAST "constraint" );
00795             if( rc < 0 )
00796             {
00797                 cerr << "failed to start container constraint element" << endl ;
00798                 return false ;
00799             }
00800 
00801             /* Write the value of the constraint */
00802             rc = xmlTextWriterWriteString( writer, BAD_CAST constraint.c_str());
00803             if( rc < 0 )
00804             {
00805                 cerr << "failed to write constraint for container" << endl ;
00806                 return "" ;
00807             }
00808 
00809             // end the container constraint element
00810             rc = xmlTextWriterEndElement( writer ) ;
00811             if( rc < 0 )
00812             {
00813                 cerr << "failed to close constraint element" << endl ;
00814                 return false ;
00815             }
00816         }
00817 
00818         string attr = attrs[(*i)] ;
00819         if( !attr.empty() )
00820         {
00821             // start the attribute element
00822             int rc = xmlTextWriterStartElement( writer, BAD_CAST "attributes" );
00823             if( rc < 0 )
00824             {
00825                 cerr << "failed to start container attributes element" << endl ;
00826                 return false ;
00827             }
00828 
00829             /* Write the value of the constraint */
00830             rc = xmlTextWriterWriteString( writer, BAD_CAST attr.c_str());
00831             if( rc < 0 )
00832             {
00833                 cerr << "failed to write attributes for container" << endl ;
00834                 return "" ;
00835             }
00836 
00837             // end the container constraint element
00838             rc = xmlTextWriterEndElement( writer ) ;
00839             if( rc < 0 )
00840             {
00841                 cerr << "failed to close attributes element" << endl ;
00842                 return false ;
00843             }
00844         }
00845 
00846         // end the container element
00847         rc = xmlTextWriterEndElement( writer ) ;
00848         if( rc < 0 )
00849         {
00850             cerr << "failed to close setContext element" << endl ;
00851             return false ;
00852         }
00853     }
00854 
00855     if( !agg_cmd.empty() )
00856     {
00857         // start the aggregation element
00858         int rc = xmlTextWriterStartElement( writer, BAD_CAST "aggregate" ) ;
00859         if( rc < 0 )
00860         {
00861             cerr << "failed to start aggregate element" << endl ;
00862             return false ;
00863         }
00864 
00865         if( !agg_handler.empty() )
00866         {
00867             /* Add the aggregation handler attribute */
00868             rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "handler",
00869                                               BAD_CAST agg_handler.c_str() ) ;
00870             if( rc < 0 )
00871             {
00872                 cerr << "failed to add the context name attribute" << endl ;
00873                 return "" ;
00874             }
00875         }
00876 
00877         /* Add the aggregation command attribute */
00878         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "cmd",
00879                                           BAD_CAST agg_cmd.c_str() ) ;
00880         if( rc < 0 )
00881         {
00882             cerr << "failed to add the context name attribute" << endl ;
00883             return "" ;
00884         }
00885 
00886         // end the aggregation element
00887         rc = xmlTextWriterEndElement( writer ) ;
00888         if( rc < 0 )
00889         {
00890             cerr << "failed to close setContext element" << endl ;
00891             return false ;
00892         }
00893     }
00894 
00895     // end the define element
00896     rc = xmlTextWriterEndElement( writer ) ;
00897     if( rc < 0 )
00898     {
00899         cerr << "failed to close setContext element" << endl ;
00900         return false ;
00901     }
00902 
00903     return true ;
00904 }
00905 
00906 bool
00907 CmdTranslation::translate_delete( BESTokenizer &t,
00908                                   xmlTextWriterPtr writer )
00909 {
00910     // delete container <container_name> [from <storage_name>];
00911     // delete containers [from <storage_name>]
00912     // delete definition <definition_name> [from <storage_name>];
00913     // delete definitions [from <storage_name>];
00914 
00915     // <deleteContainer name="container_name" space="store_name" />
00916     // <deleteContainers space="store_name" />
00917     // <deleteDefinition name="definition_name" space="store_name" />
00918     // <deleteDefinitions space="store_name" />
00919 
00920     string del_what = t.get_next_token() ;
00921     string new_cmd = "delete." + del_what ;
00922 
00923     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00924     if( p )
00925     {
00926         return p( t, writer ) ;
00927     }
00928 
00929     bool single = true ;
00930     if( del_what == "container" || del_what == "definition" )
00931     {
00932         single = true ;
00933     }
00934     else if( del_what == "containers" || del_what == "definitions" )
00935     {
00936         single = false ;
00937     }
00938     else
00939     {
00940         t.parse_error( "unknown delete command" ) ;
00941     }
00942 
00943     del_what[0] = toupper( del_what[0] ) ;
00944     string tag = "delete" + del_what ;
00945 
00946     string name ;
00947     if( single )
00948     {
00949         name = t.get_next_token() ;
00950     }
00951 
00952     string space ;
00953     string token = t.get_next_token() ;
00954     if( token == "from" )
00955     {
00956         space = t.get_next_token() ;
00957         token = t.get_next_token() ;
00958     }
00959     
00960     if( token != ";" )
00961     {
00962         t.parse_error( "delete command expected to end with semicolon" ) ;
00963     }
00964 
00965     // start the delete element
00966     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00967     if( rc < 0 )
00968     {
00969         cerr << "failed to start aggregate element" << endl ;
00970         return false ;
00971     }
00972 
00973     if( !name.empty() )
00974     {
00975         /* Add the container or definition name attribute */
00976         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00977                                           BAD_CAST name.c_str() ) ;
00978         if( rc < 0 )
00979         {
00980             cerr << "failed to add the context name attribute" << endl ;
00981             return "" ;
00982         }
00983     }
00984 
00985     if( !space.empty() )
00986     {
00987         /* Add the container or definition storage space attribute */
00988         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00989                                           BAD_CAST space.c_str() ) ;
00990         if( rc < 0 )
00991         {
00992             cerr << "failed to add the context name attribute" << endl ;
00993             return "" ;
00994         }
00995     }
00996 
00997     // end the delete element
00998     rc = xmlTextWriterEndElement( writer ) ;
00999     if( rc < 0 )
01000     {
01001         cerr << "failed to close setContext element" << endl ;
01002         return false ;
01003     }
01004 
01005     return true ;
01006 }
01007 
01008 bool
01009 CmdTranslation::translate_get( BESTokenizer &t,
01010                                xmlTextWriterPtr writer )
01011 {
01012     // get das|dds|dods|ddx for <definition_name> [return as <return_name>];
01013     // <get type="das|dds|dods|ddx" definition="def_name" returnAs="returnAs" />
01014     // get html_form for <definition> using <url>;
01015     // <get type="das|dds|dods|ddx" definition="def_name" url="url" returnAs="returnAs" />
01016     string get_what = t.get_next_token() ;
01017     string token = t.get_next_token() ;
01018     if( token != "for" )
01019     {
01020         t.parse_error( "get command expecting keyword \"for\"" ) ;
01021     }
01022 
01023     string def_name = t.get_next_token() ;
01024     string returnAs ;
01025     string url ;
01026     string starting ;
01027     string bounding ;
01028     token = t.get_next_token() ;
01029     bool done = false ;
01030     while( !done )
01031     {
01032         if( token == "return" )
01033         {
01034             token = t.get_next_token() ;
01035             if( token != "as" )
01036             {
01037                 t.parse_error( "get command expecting keyword \"as\" for return" ) ;
01038             }
01039             returnAs = t.get_next_token() ;
01040             token = t.get_next_token() ;
01041         }
01042         else if( token == "using" )
01043         {
01044             url = t.get_next_token() ;
01045             token = t.get_next_token() ;
01046         }
01047         else if( token == "contentStartId" )
01048         {
01049             starting = t.get_next_token() ;
01050             token = t.get_next_token() ;
01051         }
01052         else if( token == "mimeBoundary" )
01053         {
01054             bounding = t.get_next_token() ;
01055             token = t.get_next_token() ;
01056         }
01057         else if( token == ";" )
01058         {
01059             done = true ;
01060         }
01061         else
01062         {
01063             t.parse_error( "unexpected token in get command" ) ;
01064         }
01065     }
01066 
01067     // start the get element
01068     int rc = xmlTextWriterStartElement( writer, BAD_CAST "get" ) ;
01069     if( rc < 0 )
01070     {
01071         cerr << "failed to start aggregate element" << endl ;
01072         return false ;
01073     }
01074 
01075     /* Add the get type attribute */
01076     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
01077                                       BAD_CAST get_what.c_str() ) ;
01078     if( rc < 0 )
01079     {
01080         cerr << "failed to add the get type attribute" << endl ;
01081         return "" ;
01082     }
01083 
01084     /* Add the get definition attribute */
01085     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "definition",
01086                                       BAD_CAST def_name.c_str() ) ;
01087     if( rc < 0 )
01088     {
01089         cerr << "failed to add the get definition attribute" << endl ;
01090         return "" ;
01091     }
01092 
01093     if( !url.empty() )
01094     {
01095         /* Add the get type attribute */
01096         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "url",
01097                                           BAD_CAST url.c_str() ) ;
01098         if( rc < 0 )
01099         {
01100             cerr << "failed to add the url attribute" << endl ;
01101             return "" ;
01102         }
01103     }
01104 
01105     if( !returnAs.empty() )
01106     {
01107         /* Add the get type attribute */
01108         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "returnAs",
01109                                           BAD_CAST returnAs.c_str() ) ;
01110         if( rc < 0 )
01111         {
01112             cerr << "failed to add the returnAs attribute" << endl ;
01113             return "" ;
01114         }
01115     }
01116 
01117     if( !starting.empty() )
01118     {
01119         // start the constraint element
01120         int rc = xmlTextWriterStartElement( writer, BAD_CAST "contentStartId" );
01121         if( rc < 0 )
01122         {
01123             cerr << "failed to start contentStartId element" << endl ;
01124             return false ;
01125         }
01126 
01127         /* Write the value of the contentStartId */
01128         rc = xmlTextWriterWriteString( writer, BAD_CAST starting.c_str());
01129         if( rc < 0 )
01130         {
01131             cerr << "failed to write contentStartId for get request" << endl ;
01132             return "" ;
01133         }
01134 
01135         // end the contentStartId constraint element
01136         rc = xmlTextWriterEndElement( writer ) ;
01137         if( rc < 0 )
01138         {
01139             cerr << "failed to close constraint element" << endl ;
01140             return false ;
01141         }
01142     }
01143 
01144     if( !bounding.empty() )
01145     {
01146         // start the mimeBoundary element
01147         int rc = xmlTextWriterStartElement( writer, BAD_CAST "mimeBoundary" );
01148         if( rc < 0 )
01149         {
01150             cerr << "failed to start mimeBoundary element" << endl ;
01151             return false ;
01152         }
01153 
01154         /* Write the value of the constraint */
01155         rc = xmlTextWriterWriteString( writer, BAD_CAST bounding.c_str());
01156         if( rc < 0 )
01157         {
01158             cerr << "failed to write mimeBoundary for get request" << endl ;
01159             return "" ;
01160         }
01161 
01162         // end the mimeBoundary constraint element
01163         rc = xmlTextWriterEndElement( writer ) ;
01164         if( rc < 0 )
01165         {
01166             cerr << "failed to close mimeBoundary element" << endl ;
01167             return false ;
01168         }
01169     }
01170 
01171     // end the get element
01172     rc = xmlTextWriterEndElement( writer ) ;
01173     if( rc < 0 )
01174     {
01175         cerr << "failed to close get element" << endl ;
01176         return false ;
01177     }
01178 
01179     return true ;
01180 }
01181 
01182 void
01183 CmdTranslation::dump( ostream &strm )
01184 {
01185     strm << BESIndent::LMarg << "CmdTranslation::dump" << endl ;
01186     BESIndent::Indent() ;
01187     if( _translations.empty() )
01188     {
01189         strm << BESIndent::LMarg << "NO translations registered" << endl ;
01190     }
01191     else
01192     {
01193         strm << BESIndent::LMarg << "translations registered" << endl ;
01194         BESIndent::Indent() ;
01195         map<string,p_cmd_translator>::iterator i = _translations.begin() ;
01196         map<string,p_cmd_translator>::iterator e = _translations.end() ;
01197         for( ; i != e; i++ )
01198         {
01199             strm << BESIndent::LMarg << (*i).first << endl ;
01200         }
01201         BESIndent::UnIndent() ;
01202     }
01203     BESIndent::UnIndent() ;
01204 }
01205 

Generated on Tue May 11 20:02:06 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.4.7