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["set"] = CmdTranslation::translate_set ;
00058     _translations["set.context"] = CmdTranslation::translate_context ;
00059     _translations["set.container"] = CmdTranslation::translate_container ;
00060     _translations["define"] = CmdTranslation::translate_define ;
00061     _translations["delete"] = CmdTranslation::translate_delete ;
00062     _translations["get"] = CmdTranslation::translate_get ;
00063     return 0 ;
00064 }
00065 
00066 int
00067 CmdTranslation::terminate(void)
00068 {
00069     return 0 ;
00070 }
00071 
00072 void
00073 CmdTranslation::add_translation( const string &name, p_cmd_translator func )
00074 {
00075     CmdTranslation::_translations[name] = func ;
00076 }
00077 
00078 void
00079 CmdTranslation::remove_translation( const string &name )
00080 {
00081     map<string,p_cmd_translator>::iterator i =
00082         CmdTranslation::_translations.find( name ) ;
00083     if( i != CmdTranslation::_translations.end() )
00084     {
00085         CmdTranslation::_translations.erase( i ) ;
00086     }
00087 }
00088 
00089 string
00090 CmdTranslation::translate( const string &commands )
00091 {
00092     BESTokenizer t ;
00093     try
00094     {
00095         t.tokenize( commands.c_str() ) ;
00096 
00097         string token = t.get_first_token() ;
00098         if( token.empty() )
00099         {
00100             return "" ;
00101         }
00102     }
00103     catch( BESSyntaxUserError &e )
00104     {
00105         cerr << "failed to build tokenizer for translation" << endl ;
00106         cerr << e.get_message() << endl ;
00107         return "" ;
00108     }
00109     
00110     LIBXML_TEST_VERSION
00111 
00112     int rc;
00113     xmlTextWriterPtr writer = 0 ;
00114     xmlBufferPtr buf = 0 ;
00115     xmlChar *tmp = 0 ;
00116 
00117     /* Create a new XML buffer, to which the XML document will be
00118      * written */
00119     buf = xmlBufferCreate() ;
00120     if( buf == NULL )
00121     {
00122         cerr << "testXmlwriterMemory: Error creating the xml buffer" << endl ;
00123         return "" ;
00124     }
00125 
00126     /* Create a new XmlWriter for memory, with no compression.
00127      * Remark: there is no compression for this kind of xmlTextWriter */
00128     writer = xmlNewTextWriterMemory( buf, 0 ) ;
00129     if( writer == NULL )
00130     {
00131         cerr << "testXmlwriterMemory: Error creating the xml writer" << endl ;
00132         return "" ;
00133     }
00134 
00135     /* Start the document with the xml default for the version,
00136      * encoding ISO 8859-1 and the default for the standalone
00137      * declaration. MY_ENCODING defined at top of this file*/
00138     rc = xmlTextWriterStartDocument( writer, NULL, MY_ENCODING, NULL ) ;
00139     if( rc < 0 )
00140     {
00141         cerr << "testXmlwriterMemory: Error at xmlTextWriterStartDocument"
00142              << endl ;
00143         xmlFreeTextWriter( writer ) ;
00144         return "" ;
00145     }
00146 
00147     /* Start an element named "request". Since thist is the first
00148      * element, this will be the root element of the document. */
00149     rc = xmlTextWriterStartElement( writer, BAD_CAST "request" ) ;
00150     if( rc < 0 )
00151     {
00152         cerr << "testXmlwriterMemory: Error at xmlTextWriterStartElement"
00153              << endl ;
00154         xmlFreeTextWriter( writer ) ;
00155         return "" ;
00156     }
00157 
00158     /* Add the request id attribute */
00159     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "reqID",
00160                                       BAD_CAST "some_unique_value" ) ;
00161     if( rc < 0 )
00162     {
00163         cerr << "failed to add the request id attribute" << endl ;
00164         return "" ;
00165     }
00166 
00167     bool status = do_translate( t, writer ) ;
00168     if( !status )
00169     {
00170         xmlFreeTextWriter( writer ) ;
00171         return "" ;
00172     }
00173 
00174     // this should end the request element
00175     rc = xmlTextWriterEndElement( writer ) ;
00176     if( rc < 0 )
00177     {
00178         cerr << "failed to close request element" << endl ;
00179         xmlFreeTextWriter( writer ) ;
00180         return "" ;
00181     }
00182 
00183     rc = xmlTextWriterEndDocument( writer ) ;
00184     if( rc < 0 )
00185     {
00186         cerr << "failed to end the document" << endl ;
00187         return "" ;
00188     }
00189 
00190     xmlFreeTextWriter(writer);
00191 
00192     // get the xml document as a string and return
00193     string doc ;
00194     if( !buf->content )
00195     {
00196         cerr << "failed to retrieve document as string" << endl ;
00197     }
00198     else
00199     {
00200         doc = (char *)buf->content ;
00201     }
00202 
00203     xmlBufferFree( buf ) ;
00204 
00205     xmlCleanupParser();
00206 
00207     return doc ;
00208 }
00209 
00210 bool
00211 CmdTranslation::do_translate( BESTokenizer &t, xmlTextWriterPtr writer )
00212 {
00213     string token = t.get_current_token() ;
00214     CmdTranslation::p_cmd_translator p = _translations[token] ;
00215     if( !p )
00216     {
00217         cerr << endl << "Invalid command " << token << endl << endl ;
00218         return false ;
00219     }
00220 
00221     try
00222     {
00223         bool status = p( t, writer ) ;
00224         if( !status )
00225         {
00226             return status ;
00227         }
00228     }
00229     catch( BESSyntaxUserError &e )
00230     {
00231         cerr << e.get_message() << endl ;
00232         return false ;
00233     }
00234 
00235     // if this throws an exception then there are no more tokens. Catch it
00236     // and ignore the exception. This means we're done.
00237     try
00238     {
00239         token = t.get_next_token() ;
00240     }
00241     catch( BESSyntaxUserError &e )
00242     {
00243         token.clear() ;
00244     }
00245 
00246     if( token.empty() )
00247     {
00248         // we are done.
00249         return true ;
00250     }
00251 
00252     // more translation to do, so call do_translate again. It will grab the
00253     // current token which we just got.
00254     return do_translate( t, writer ) ;
00255 }
00256 
00257 bool
00258 CmdTranslation::translate_show( BESTokenizer &t, xmlTextWriterPtr writer )
00259 {
00260     CmdTranslation::set_show( true ) ;
00261 
00262     string show_what = t.get_next_token() ;
00263     if( show_what.empty() )
00264     {
00265         t.parse_error( "show command must be followed by target" ) ;
00266     }
00267 
00268     string new_cmd = "show." + show_what ;
00269     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00270     if( p )
00271     {
00272         return p( t, writer ) ;
00273     }
00274 
00275     string semi = t.get_next_token() ;
00276     if( semi != ";" )
00277     {
00278         string err = (string)"show " + show_what
00279                      + " commands must end with a semicolon" ;
00280         t.parse_error( err ) ;
00281     }
00282     show_what[0] = toupper( show_what[0] ) ;
00283     string tag = "show" + show_what ;
00284 
00285     // start the show element
00286     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00287     if( rc < 0 )
00288     {
00289         cerr << "failed to start " << tag << " element" << endl ;
00290         return false ;
00291     }
00292 
00293     // end the show element
00294     rc = xmlTextWriterEndElement( writer ) ;
00295     if( rc < 0 )
00296     {
00297         cerr << "failed to close " << tag << " element" << endl ;
00298         return false ;
00299     }
00300 
00301     return true ;
00302 }
00303 
00304 bool
00305 CmdTranslation::translate_catalog( BESTokenizer &t, xmlTextWriterPtr writer )
00306 {
00307     // show catalog|info [for node]
00308     // <showCatalog node="" />
00309     string show_what = t.get_current_token() ;
00310     if( show_what.empty() || ( show_what != "info" && show_what != "catalog" ) )
00311     {
00312         t.parse_error( "show command must be info or catalog" ) ;
00313     }
00314 
00315     show_what[0] = toupper( show_what[0] ) ;
00316     string tag = "show" + show_what ;
00317 
00318     string token = t.get_next_token() ;
00319     string node ;
00320     if( token == "for" )
00321     {
00322         node = t.get_next_token() ;
00323         if( node == ";" )
00324         {
00325             t.parse_error( "show catalog command expecting node" ) ;
00326         }
00327         node = t.remove_quotes( node ) ;
00328         token = t.get_next_token() ;
00329     }
00330     if( token != ";" )
00331     {
00332         t.parse_error( "show command must be terminated by a semicolon" ) ;
00333     }
00334 
00335     // start the show element
00336     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00337     if( rc < 0 )
00338     {
00339         cerr << "failed to start " << tag << " element" << endl ;
00340         return false ;
00341     }
00342 
00343     /* Add the catalog node */
00344     if( !node.empty() )
00345     {
00346         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "node",
00347                                           BAD_CAST node.c_str() ) ;
00348         if( rc < 0 )
00349         {
00350             cerr << "failed to add the catalog node attribute" << endl ;
00351             return "" ;
00352         }
00353     }
00354 
00355     // end the show element
00356     rc = xmlTextWriterEndElement( writer ) ;
00357     if( rc < 0 )
00358     {
00359         cerr << "failed to close " << tag << " element" << endl ;
00360         return false ;
00361     }
00362 
00363     return true ;
00364 }
00365 
00366 bool
00367 CmdTranslation::translate_set( BESTokenizer &t,
00368                                xmlTextWriterPtr writer )
00369 {
00370     string set_what = t.get_next_token() ;
00371     if( set_what.empty() )
00372     {
00373         t.parse_error( "set command must be followed by target" ) ;
00374     }
00375 
00376     string new_cmd = "set." + set_what ;
00377     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00378     if( !p )
00379     {
00380         cerr << "no such command: set " << set_what << endl ;
00381         return false ;
00382     }
00383 
00384     return p( t, writer ) ;
00385 }
00386 
00387 bool
00388 CmdTranslation::translate_context( BESTokenizer &t,
00389                                    xmlTextWriterPtr writer )
00390 {
00391     // set context blee to blah ;
00392     // <setContext name="dap_format">dap2</setContext>
00393     string name = t.get_next_token() ;
00394     if( name == ";" )
00395     {
00396         t.parse_error( "missing context name" ) ;
00397     }
00398     string to = t.get_next_token() ;
00399     if( to != "to" )
00400     {
00401         t.parse_error( "missing word \"to\" in set context" ) ;
00402     }
00403     string value = t.get_next_token() ;
00404     if( value == ";" )
00405     {
00406         t.parse_error( "missing context value" ) ;
00407     }
00408     string semi = t.get_next_token() ;
00409     if( semi != ";" )
00410     {
00411         t.parse_error( "set context command must end with semicolon" ) ;
00412     }
00413 
00414     // start the setContext element
00415     int rc = xmlTextWriterStartElement( writer, BAD_CAST "setContext" ) ;
00416     if( rc < 0 )
00417     {
00418         cerr << "failed to start setContext element" << endl ;
00419         return false ;
00420     }
00421 
00422     /* Add the context name attribute */
00423     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00424                                       BAD_CAST name.c_str() ) ;
00425     if( rc < 0 )
00426     {
00427         cerr << "failed to add the context name attribute" << endl ;
00428         return "" ;
00429     }
00430 
00431     /* Write the value of the context */
00432     rc = xmlTextWriterWriteString( writer, BAD_CAST value.c_str() ) ;
00433     if( rc < 0 )
00434     {
00435         cerr << "failed to write the value of the context" << endl ;
00436         return "" ;
00437     }
00438 
00439     // end the setContext element
00440     rc = xmlTextWriterEndElement( writer ) ;
00441     if( rc < 0 )
00442     {
00443         cerr << "failed to close setContext element" << endl ;
00444         return false ;
00445     }
00446 
00447     return true ;
00448 }
00449 
00450 bool
00451 CmdTranslation::translate_container( BESTokenizer &t,
00452                                      xmlTextWriterPtr writer )
00453 {
00454     // set container in space values name,value,type;
00455     // <setContainer name="c" space="catalog">/data/fnoc1.nc</setContainer>
00456     string token = t.get_next_token() ;
00457     string space ;
00458     if( token == "in" )
00459     {
00460         space = t.get_next_token() ;
00461         if( space == "values" || space == ";" )
00462         {
00463             t.parse_error( "expecting name of container storage" ) ;
00464         }
00465         token = t.get_next_token() ;
00466     }
00467     if( token != "values" )
00468     {
00469         t.parse_error( "missing values for set container" ) ;
00470     }
00471 
00472     string name = t.get_next_token() ;
00473     if( name == ";" || name == "," )
00474     {
00475         t.parse_error( "expecting name of the container" ) ;
00476     }
00477 
00478     token = t.get_next_token() ;
00479     if( token != "," )
00480     {
00481         t.parse_error( "missing comma in set container after name" ) ;
00482     }
00483 
00484     string value = t.get_next_token() ;
00485     if( value == "," || value == ";" )
00486     {
00487         t.parse_error( "expecting location of the container" ) ;
00488     }
00489 
00490     token = t.get_next_token() ;
00491     string type ;
00492     if( token == "," )
00493     {
00494         type = t.get_next_token() ;
00495         if( type == ";" )
00496         {
00497             t.parse_error( "expecting container type" ) ;
00498         }
00499         token = t.get_next_token() ;
00500     }
00501 
00502     if( token != ";" )
00503     {
00504         t.parse_error( "set container command must end with semicolon" ) ;
00505     }
00506 
00507     // start the setContainer element
00508     int rc = xmlTextWriterStartElement( writer, BAD_CAST "setContainer" ) ;
00509     if( rc < 0 )
00510     {
00511         cerr << "failed to start setContext element" << endl ;
00512         return false ;
00513     }
00514 
00515     /* Add the container name attribute */
00516     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00517                                       BAD_CAST name.c_str() ) ;
00518     if( rc < 0 )
00519     {
00520         cerr << "failed to add the context name attribute" << endl ;
00521         return "" ;
00522     }
00523 
00524     if( !space.empty() )
00525     {
00526         /* Add the container space attribute */
00527         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00528                                           BAD_CAST space.c_str() ) ;
00529         if( rc < 0 )
00530         {
00531             cerr << "failed to add the container space attribute" << endl ;
00532             return "" ;
00533         }
00534     }
00535 
00536     if( !type.empty() )
00537     {
00538         /* Add the container space attribute */
00539         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
00540                                           BAD_CAST type.c_str() ) ;
00541         if( rc < 0 )
00542         {
00543             cerr << "failed to add the container type attribute" << endl ;
00544             return "" ;
00545         }
00546     }
00547 
00548     /* Write the value of the container */
00549     rc = xmlTextWriterWriteString( writer, BAD_CAST value.c_str() ) ;
00550     if( rc < 0 )
00551     {
00552         cerr << "failed to write the location of the container" << endl ;
00553         return "" ;
00554     }
00555 
00556     // end the setContainer element
00557     rc = xmlTextWriterEndElement( writer ) ;
00558     if( rc < 0 )
00559     {
00560         cerr << "failed to close setContext element" << endl ;
00561         return false ;
00562     }
00563 
00564     return true ;
00565 }
00566 
00567 bool
00568 CmdTranslation::translate_define( BESTokenizer &t,
00569                                   xmlTextWriterPtr writer )
00570 {
00571     // define <def_name> [in <storage_name>] as <container_list> [where // <container_x>.constraint="<constraint>",<container_x>.attributes="<attribute_list>"] // [aggregate by "<aggregation_command>"];
00572 
00573     // <define name="definition_name" space="store_name">
00574     //  <container name="container_name">
00575     //      <constraint>legal_constraint</constraint>
00576     //      <attributes>attribute_list</attributes>
00577     //  </container>
00578     //  <aggregate handler="someHandler" cmd="someCommand" />
00579     // </define>
00580     string name = t.get_next_token() ;
00581     string space ;
00582     string token = t.get_next_token() ;
00583     if( token == "in" )
00584     {
00585         space = t.get_next_token() ;
00586         token = t.get_next_token() ;
00587     }
00588 
00589     if( token != "as" )
00590     {
00591         t.parse_error( "Looking for keyword as in define command" ) ;
00592     }
00593 
00594     list<string> containers ;
00595     map<string,string> clist ;
00596     bool done = false ;
00597     while( !done )
00598     {
00599         token = t.get_next_token() ;
00600         containers.push_back( token ) ;
00601         clist[token] = token ;
00602         token = t.get_next_token() ;
00603         if( token != "," )
00604         {
00605             done = true ;
00606         }
00607     }
00608 
00609     // constraints and attributes
00610     map<string,string> constraints ;
00611     map<string,string> attrs ;
00612     if( token == "with" )
00613     {
00614         token = t.get_next_token() ;
00615         unsigned int type ;
00616         while( token != "aggregate" && token != ";" )
00617         {
00618             string c = t.parse_container_name( token, type ) ;
00619             if( clist[c] != c )
00620             {
00621                 t.parse_error( "contstraint container does not exist" ) ;
00622             }
00623             if( type == 1 )
00624             {
00625                 // constraint
00626                 constraints[c] = t.remove_quotes( t.get_next_token() ) ;
00627             }
00628             else if( type == 2 )
00629             {
00630                 // attributed
00631                 attrs[c] = t.remove_quotes( t.get_next_token() ) ;
00632             }
00633             else
00634             {
00635                 t.parse_error( "unknown constraint type" ) ;
00636             }
00637             token = t.get_next_token() ;
00638             if( token == "," )
00639             {
00640                 token = t.get_next_token() ;
00641             }
00642         }
00643     }
00644 
00645     string agg_handler ;
00646     string agg_cmd ;
00647     if( token == "aggregate" )
00648     {
00649         token = t.get_next_token() ;
00650         if( token == "by" )
00651         {
00652             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00653             token = t.get_next_token() ;
00654             if( token != "using" )
00655             {
00656                 t.parse_error( "aggregation expecting keyword \"using\"");
00657             }
00658             agg_handler = t.get_next_token() ;
00659         }
00660         else if( token == "using" )
00661         {
00662             agg_handler = t.get_next_token() ;
00663             token = t.get_next_token() ;
00664             if( token != "by" )
00665             {
00666                 t.parse_error( "aggregation expecting keyword \"by\"");
00667             }
00668             agg_cmd = t.remove_quotes( t.get_next_token() ) ;
00669         }
00670         else
00671         {
00672             t.parse_error( "aggregation expecting keyword \"by\" or \"using\"");
00673         }
00674 
00675         token = t.get_next_token() ;
00676     }
00677 
00678     if( token != ";" )
00679     {
00680         t.parse_error( "define command must end with semicolon" ) ;
00681     }
00682 
00683     // start the define element
00684     int rc = xmlTextWriterStartElement( writer, BAD_CAST "define" ) ;
00685     if( rc < 0 )
00686     {
00687         cerr << "failed to start setContext element" << endl ;
00688         return false ;
00689     }
00690 
00691     /* Add the definition name attribute */
00692     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00693                                       BAD_CAST name.c_str() ) ;
00694     if( rc < 0 )
00695     {
00696         cerr << "failed to add the context name attribute" << endl ;
00697         return "" ;
00698     }
00699 
00700     if( !space.empty() )
00701     {
00702         /* Add the definition space attribute */
00703         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00704                                           BAD_CAST space.c_str() ) ;
00705         if( rc < 0 )
00706         {
00707             cerr << "failed to add the container space attribute" << endl ;
00708             return "" ;
00709         }
00710     }
00711 
00712     list<string>::iterator i = containers.begin() ;
00713     list<string>::iterator e = containers.end() ;
00714     for( ; i != e; i++ )
00715     {
00716         // start the container element
00717         int rc = xmlTextWriterStartElement( writer, BAD_CAST "container" ) ;
00718         if( rc < 0 )
00719         {
00720             cerr << "failed to start container element" << endl ;
00721             return false ;
00722         }
00723 
00724         /* Add the container name attribute */
00725         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00726                                           BAD_CAST (*i).c_str() ) ;
00727         if( rc < 0 )
00728         {
00729             cerr << "failed to add the context name attribute" << endl ;
00730             return "" ;
00731         }
00732 
00733         // add constraints and attributes elements here
00734         string constraint = constraints[(*i)] ;
00735         if( !constraint.empty() )
00736         {
00737             // start the constraint element
00738             int rc = xmlTextWriterStartElement( writer, BAD_CAST "constraint" );
00739             if( rc < 0 )
00740             {
00741                 cerr << "failed to start container constraint element" << endl ;
00742                 return false ;
00743             }
00744 
00745             /* Write the value of the constraint */
00746             rc = xmlTextWriterWriteString( writer, BAD_CAST constraint.c_str());
00747             if( rc < 0 )
00748             {
00749                 cerr << "failed to write constraint for container" << endl ;
00750                 return "" ;
00751             }
00752 
00753             // end the container constraint element
00754             rc = xmlTextWriterEndElement( writer ) ;
00755             if( rc < 0 )
00756             {
00757                 cerr << "failed to close constraint element" << endl ;
00758                 return false ;
00759             }
00760         }
00761 
00762         string attr = attrs[(*i)] ;
00763         if( !attr.empty() )
00764         {
00765             // start the attribute element
00766             int rc = xmlTextWriterStartElement( writer, BAD_CAST "attributes" );
00767             if( rc < 0 )
00768             {
00769                 cerr << "failed to start container attributes element" << endl ;
00770                 return false ;
00771             }
00772 
00773             /* Write the value of the constraint */
00774             rc = xmlTextWriterWriteString( writer, BAD_CAST attr.c_str());
00775             if( rc < 0 )
00776             {
00777                 cerr << "failed to write attributes for container" << endl ;
00778                 return "" ;
00779             }
00780 
00781             // end the container constraint element
00782             rc = xmlTextWriterEndElement( writer ) ;
00783             if( rc < 0 )
00784             {
00785                 cerr << "failed to close attributes element" << endl ;
00786                 return false ;
00787             }
00788         }
00789 
00790         // end the container element
00791         rc = xmlTextWriterEndElement( writer ) ;
00792         if( rc < 0 )
00793         {
00794             cerr << "failed to close setContext element" << endl ;
00795             return false ;
00796         }
00797     }
00798 
00799     if( !agg_cmd.empty() )
00800     {
00801         // start the aggregation element
00802         int rc = xmlTextWriterStartElement( writer, BAD_CAST "aggregate" ) ;
00803         if( rc < 0 )
00804         {
00805             cerr << "failed to start aggregate element" << endl ;
00806             return false ;
00807         }
00808 
00809         if( !agg_handler.empty() )
00810         {
00811             /* Add the aggregation handler attribute */
00812             rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "handler",
00813                                               BAD_CAST agg_handler.c_str() ) ;
00814             if( rc < 0 )
00815             {
00816                 cerr << "failed to add the context name attribute" << endl ;
00817                 return "" ;
00818             }
00819         }
00820 
00821         /* Add the aggregation command attribute */
00822         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "cmd",
00823                                           BAD_CAST agg_cmd.c_str() ) ;
00824         if( rc < 0 )
00825         {
00826             cerr << "failed to add the context name attribute" << endl ;
00827             return "" ;
00828         }
00829 
00830         // end the aggregation element
00831         rc = xmlTextWriterEndElement( writer ) ;
00832         if( rc < 0 )
00833         {
00834             cerr << "failed to close setContext element" << endl ;
00835             return false ;
00836         }
00837     }
00838 
00839     // end the define element
00840     rc = xmlTextWriterEndElement( writer ) ;
00841     if( rc < 0 )
00842     {
00843         cerr << "failed to close setContext element" << endl ;
00844         return false ;
00845     }
00846 
00847     return true ;
00848 }
00849 
00850 bool
00851 CmdTranslation::translate_delete( BESTokenizer &t,
00852                                   xmlTextWriterPtr writer )
00853 {
00854     // delete container <container_name> [from <storage_name>];
00855     // delete containers [from <storage_name>]
00856     // delete definition <definition_name> [from <storage_name>];
00857     // delete definitions [from <storage_name>];
00858 
00859     // <deleteContainer name="container_name" space="store_name" />
00860     // <deleteContainers space="store_name" />
00861     // <deleteDefinition name="definition_name" space="store_name" />
00862     // <deleteDefinitions space="store_name" />
00863 
00864     string del_what = t.get_next_token() ;
00865     string new_cmd = "delete." + del_what ;
00866 
00867     CmdTranslation::p_cmd_translator p = _translations[new_cmd] ;
00868     if( p )
00869     {
00870         return p( t, writer ) ;
00871     }
00872 
00873     bool single = true ;
00874     if( del_what == "container" || del_what == "definition" )
00875     {
00876         single = true ;
00877     }
00878     else if( del_what == "containers" || del_what == "definitions" )
00879     {
00880         single = false ;
00881     }
00882     else
00883     {
00884         t.parse_error( "unknown delete command" ) ;
00885     }
00886 
00887     del_what[0] = toupper( del_what[0] ) ;
00888     string tag = "delete" + del_what ;
00889 
00890     string name ;
00891     if( single )
00892     {
00893         name = t.get_next_token() ;
00894     }
00895 
00896     string space ;
00897     string token = t.get_next_token() ;
00898     if( token == "from" )
00899     {
00900         space = t.get_next_token() ;
00901         token = t.get_next_token() ;
00902     }
00903     
00904     if( token != ";" )
00905     {
00906         t.parse_error( "delete command expected to end with semicolon" ) ;
00907     }
00908 
00909     // start the delete element
00910     int rc = xmlTextWriterStartElement( writer, BAD_CAST tag.c_str() ) ;
00911     if( rc < 0 )
00912     {
00913         cerr << "failed to start aggregate element" << endl ;
00914         return false ;
00915     }
00916 
00917     if( !name.empty() )
00918     {
00919         /* Add the container or definition name attribute */
00920         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "name",
00921                                           BAD_CAST name.c_str() ) ;
00922         if( rc < 0 )
00923         {
00924             cerr << "failed to add the context name attribute" << endl ;
00925             return "" ;
00926         }
00927     }
00928 
00929     if( !space.empty() )
00930     {
00931         /* Add the container or definition storage space attribute */
00932         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "space",
00933                                           BAD_CAST space.c_str() ) ;
00934         if( rc < 0 )
00935         {
00936             cerr << "failed to add the context name attribute" << endl ;
00937             return "" ;
00938         }
00939     }
00940 
00941     // end the delete element
00942     rc = xmlTextWriterEndElement( writer ) ;
00943     if( rc < 0 )
00944     {
00945         cerr << "failed to close setContext element" << endl ;
00946         return false ;
00947     }
00948 
00949     return true ;
00950 }
00951 
00952 bool
00953 CmdTranslation::translate_get( BESTokenizer &t,
00954                                xmlTextWriterPtr writer )
00955 {
00956     // get das|dds|dods|ddx for <definition_name> [return as <return_name>];
00957     // <get type="das|dds|dods|ddx" definition="def_name" returnAs="returnAs" />
00958     // get html_form for <definition> using <url>;
00959     // <get type="das|dds|dods|ddx" definition="def_name" url="url" returnAs="returnAs" />
00960     string get_what = t.get_next_token() ;
00961     string token = t.get_next_token() ;
00962     if( token != "for" )
00963     {
00964         t.parse_error( "get command expecting keyword \"for\"" ) ;
00965     }
00966 
00967     string def_name = t.get_next_token() ;
00968     string returnAs ;
00969     string url ;
00970     token = t.get_next_token() ;
00971     bool done = false ;
00972     while( !done )
00973     {
00974         if( token == "return" )
00975         {
00976             token = t.get_next_token() ;
00977             if( token != "as" )
00978             {
00979                 t.parse_error( "get command expecting keyword \"as\" for return" ) ;
00980             }
00981             returnAs = t.get_next_token() ;
00982             token = t.get_next_token() ;
00983         }
00984         else if( token == "using" )
00985         {
00986             url = t.get_next_token() ;
00987             token = t.get_next_token() ;
00988         }
00989         else if( token == ";" )
00990         {
00991             done = true ;
00992         }
00993         else
00994         {
00995             t.parse_error( "unexpected token in get command" ) ;
00996         }
00997     }
00998 
00999     // start the get element
01000     int rc = xmlTextWriterStartElement( writer, BAD_CAST "get" ) ;
01001     if( rc < 0 )
01002     {
01003         cerr << "failed to start aggregate element" << endl ;
01004         return false ;
01005     }
01006 
01007     /* Add the get type attribute */
01008     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "type",
01009                                       BAD_CAST get_what.c_str() ) ;
01010     if( rc < 0 )
01011     {
01012         cerr << "failed to add the get type attribute" << endl ;
01013         return "" ;
01014     }
01015 
01016     /* Add the get definition attribute */
01017     rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "definition",
01018                                       BAD_CAST def_name.c_str() ) ;
01019     if( rc < 0 )
01020     {
01021         cerr << "failed to add the get definition attribute" << endl ;
01022         return "" ;
01023     }
01024 
01025     if( !url.empty() )
01026     {
01027         /* Add the get type attribute */
01028         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "url",
01029                                           BAD_CAST url.c_str() ) ;
01030         if( rc < 0 )
01031         {
01032             cerr << "failed to add the url attribute" << endl ;
01033             return "" ;
01034         }
01035     }
01036 
01037     if( !returnAs.empty() )
01038     {
01039         /* Add the get type attribute */
01040         rc = xmlTextWriterWriteAttribute( writer, BAD_CAST "returnAs",
01041                                           BAD_CAST returnAs.c_str() ) ;
01042         if( rc < 0 )
01043         {
01044             cerr << "failed to add the returnAs attribute" << endl ;
01045             return "" ;
01046         }
01047     }
01048 
01049     // end the get element
01050     rc = xmlTextWriterEndElement( writer ) ;
01051     if( rc < 0 )
01052     {
01053         cerr << "failed to close setContext element" << endl ;
01054         return false ;
01055     }
01056 
01057     return true ;
01058 }
01059 
01060 void
01061 CmdTranslation::dump( ostream &strm )
01062 {
01063     strm << BESIndent::LMarg << "CmdTranslation::dump" << endl ;
01064     BESIndent::Indent() ;
01065     if( _translations.empty() )
01066     {
01067         strm << BESIndent::LMarg << "NO translations registered" << endl ;
01068     }
01069     else
01070     {
01071         strm << BESIndent::LMarg << "translations registered" << endl ;
01072         BESIndent::Indent() ;
01073         map<string,p_cmd_translator>::iterator i = _translations.begin() ;
01074         map<string,p_cmd_translator>::iterator e = _translations.end() ;
01075         for( ; i != e; i++ )
01076         {
01077             strm << BESIndent::LMarg << (*i).first << endl ;
01078         }
01079         BESIndent::UnIndent() ;
01080     }
01081     BESIndent::UnIndent() ;
01082 }
01083 

Generated on 18 Feb 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.6.1