OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
StandAloneApp.cc
Go to the documentation of this file.
00001 // StandAloneApp.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 <unistd.h>  // for getopt
00034 #include <signal.h>
00035 
00036 #include <iostream>
00037 #include <string>
00038 #include <fstream>
00039 
00040 using std::cout ;
00041 using std::cerr ;
00042 using std::endl ;
00043 using std::flush ;
00044 using std::string ;
00045 using std::ofstream ;
00046 
00047 #include "StandAloneApp.h"
00048 #include "StandAloneClient.h"
00049 #include "BESError.h"
00050 #include "BESDebug.h"
00051 #include "BESDefaultModule.h"
00052 #include "BESXMLDefaultCommands.h"
00053 #include "TheBESKeys.h"
00054 #include "CmdTranslation.h"
00055 
00056 StandAloneApp::StandAloneApp()
00057     : BESModuleApp(),
00058       _client( 0 ),
00059       _outputStrm( 0 ),
00060       _inputStrm( 0 ),
00061       _createdInputStrm( false ),
00062       _repeat( 0 )
00063 {
00064 }
00065 
00066 StandAloneApp::~StandAloneApp()
00067 {
00068     if( _client )
00069     {
00070         delete _client ;
00071         _client = 0 ;
00072     }
00073 }
00074 
00075 void
00076 StandAloneApp::showVersion()
00077 {
00078     cout << appName() << ": version 2.0" << endl ;
00079 }
00080 
00081 void
00082 StandAloneApp::showUsage( )
00083 {
00084     cout << endl ;
00085     cout << appName() << ": the following flags are available:" << endl ;
00086     cout << "    -c <configFile> - specifies a BES configuration file to use" << endl ;
00087     cout << "    -x <command> - specifies a command for the server to execute" << endl ;
00088     cout << "    -i <inputFile> - specifies a file name for a sequence of input commands" << endl ;
00089     cout << "    -f <outputFile> - specifies a file name to output the results of the input" << endl ;
00090     cout << "    -d - sets the optional debug flag for the client session" << endl ;
00091     cout << "    -r <num> - repeat the command(s) num times" << endl ;
00092     cout << "    -? - display this list of flags" << endl ;
00093     cout << endl ;
00094     BESDebug::Help( cout ) ;
00095 }
00096 
00097 int
00098 StandAloneApp::initialize( int argc, char **argv )
00099 {
00100     CmdTranslation::initialize( argc, argv ) ;
00101 
00102     string outputStr = "" ;
00103     string inputStr = "" ;
00104     string repeatStr = "" ;
00105 
00106     bool badUsage = false ;
00107 
00108     int c ;
00109 
00110     while( ( c = getopt( argc, argv, "?vc:d:x:f:i:r:" ) ) != EOF )
00111     {
00112         switch( c )
00113         {
00114             case 'c':
00115                 TheBESKeys::ConfigFile = optarg ;
00116                 break ;
00117             case 'd':
00118                 BESDebug::SetUp( optarg ) ;
00119                 break ;
00120             case 'v':
00121                 {
00122                     showVersion() ;
00123                     exit( 0 ) ;
00124                 }
00125                 break ;
00126             case 'x':
00127                 _cmd = optarg ;
00128                 break ;
00129             case 'f':
00130                 outputStr = optarg ;
00131                 break ;
00132             case 'i':
00133                 inputStr = optarg ;
00134                 break ;
00135             case 'r':
00136                 repeatStr = optarg ;
00137                 break ;
00138             case '?':
00139                 {
00140                     showUsage() ;
00141                     exit( 0 ) ;
00142                 }
00143                 break ;
00144         }
00145     }
00146 
00147     if( outputStr != "" )
00148     {
00149         if( _cmd == "" && inputStr == "" )
00150         {
00151             cerr << "When specifying an output file you must either "
00152                  << "specify a command or an input file"
00153                  << endl ;
00154             badUsage = true ;
00155         }
00156         else if( _cmd != "" && inputStr != "" )
00157         {
00158             cerr << "You must specify either a command or an input file on "
00159                  << "the command line, not both"
00160                  << endl ;
00161             badUsage = true ;
00162         }
00163     }
00164 
00165     if( badUsage == true )
00166     {
00167         showUsage( ) ;
00168         return 1 ;
00169     }
00170 
00171     if( outputStr != "" )
00172     {
00173         _outputStrm = new ofstream( outputStr.c_str() ) ;
00174         if( !(*_outputStrm) )
00175         {
00176             cerr << "could not open the output file " << outputStr << endl ;
00177             badUsage = true ;
00178         }
00179     }
00180 
00181     if( inputStr != "" )
00182     {
00183         _inputStrm = new ifstream( inputStr.c_str() ) ;
00184         if( !(*_inputStrm) )
00185         {
00186             cerr << "could not open the input file " << inputStr << endl ;
00187             badUsage = true ;
00188         }
00189         _createdInputStrm = true ;
00190     }
00191 
00192     if( !repeatStr.empty() )
00193     {
00194         _repeat = atoi( repeatStr.c_str() ) ;
00195         if( !_repeat && repeatStr != "0" )
00196         {
00197             cerr << "repeat number invalid: " << repeatStr << endl ;
00198             badUsage = true ;
00199         }
00200         if( !_repeat )
00201         {
00202             _repeat = 1 ;
00203         }
00204     }
00205 
00206     if( badUsage == true )
00207     {
00208         showUsage( ) ;
00209         return 1 ;
00210     }
00211 
00212     try
00213     {
00214         BESDEBUG( "standalone", "ServerApp: initializing default module ... "
00215                                 << endl ) ;
00216         BESDefaultModule::initialize( argc, argv ) ;
00217         BESDEBUG( "standalone", "ServerApp: done initializing default module"
00218                                 << endl ) ;
00219 
00220         BESDEBUG( "standalone", "ServerApp: initializing default commands ... "
00221                                 << endl ) ;
00222         BESXMLDefaultCommands::initialize( argc, argv ) ;
00223         BESDEBUG( "standalone", "ServerApp: done initializing default commands"
00224                                 << endl ) ;
00225 
00226         BESDEBUG( "standalone", "ServerApp: initializing loaded modules ... "
00227                                 << endl ) ;
00228         int retval = BESModuleApp::initialize( argc, argv ) ;
00229         BESDEBUG( "standalone", "ServerApp: done initializing loaded modules"
00230                                 << endl ) ;
00231         if( retval )
00232             return retval ;
00233     }
00234     catch( BESError &e )
00235     {
00236         cerr << "Failed to initialize stand alone app" << endl ;
00237         cerr << e.get_message() << endl ;
00238         return 1 ;
00239     }
00240 
00241     BESDEBUG( "standalone", "StandAloneApp: initialized settings:"
00242                             << endl << *this ) ;
00243 
00244     return 0 ;
00245 }
00246 
00247 int
00248 StandAloneApp::run()
00249 {
00250     try
00251     {
00252         _client = new StandAloneClient ;
00253         if( _outputStrm )
00254         {
00255             _client->setOutput( _outputStrm, true ) ;
00256         }
00257         else
00258         {
00259             _client->setOutput( &cout, false ) ;
00260         }
00261         BESDEBUG( "standalone", "OK" << endl ) ;
00262     }
00263     catch( BESError &e )
00264     {
00265         if( _client )
00266         {
00267             delete _client ;
00268             _client = 0 ;
00269         }
00270         BESDEBUG( "standalone", "FAILED" << endl ) ;
00271         cerr << "error starting the client" << endl ;
00272         cerr << e.get_message() << endl ;
00273         exit( 1 ) ;
00274     }
00275 
00276     try
00277     {
00278         if( _cmd != "" )
00279         {
00280             _client->executeCommands( _cmd, _repeat ) ;
00281         }
00282         else if( _inputStrm )
00283         {
00284             _client->executeCommands( *_inputStrm, _repeat ) ;
00285         }
00286         else
00287         {
00288             _client->interact() ;
00289         }
00290     }
00291     catch( BESError &e )
00292     {
00293         cerr << "error processing commands" << endl ;
00294         cerr << e.get_message() << endl ;
00295     }
00296 
00297     try
00298     {
00299         BESDEBUG( "standalone", "StandAloneApp: shutting down client ... "
00300                                 << endl ) ;
00301         if( _client )
00302         {
00303             delete _client ;
00304             _client = 0 ;
00305         }
00306         BESDEBUG( "standalone", "OK" << endl ) ;
00307 
00308         BESDEBUG( "standalone", "StandAloneApp: closing input stream ... "
00309                                 << endl ) ;
00310         if( _createdInputStrm )
00311         {
00312             _inputStrm->close() ;
00313             delete _inputStrm ;
00314             _inputStrm = 0 ;
00315         }
00316         BESDEBUG( "standalone", "OK" << endl ) ;
00317     }
00318     catch( BESError &e )
00319     {
00320         BESDEBUG( "standalone", "FAILED" << endl ) ;
00321         cerr << "error closing the client" << endl ;
00322         cerr << e.get_message() << endl ;
00323         return 1 ;
00324     }
00325 
00326     return 0 ;
00327 }
00328 
00334 int
00335 StandAloneApp::terminate( int sig )
00336 {
00337     BESDEBUG( "standalone", "ServerApp: terminating loaded modules ... "
00338                             << endl ) ;
00339     BESModuleApp::terminate( sig ) ;
00340     BESDEBUG( "standalone", "ServerApp: done terminating loaded modules"
00341                             << endl ) ;
00342 
00343     BESDEBUG( "standalone", "ServerApp: terminating default commands ...  "
00344                             << endl ) ;
00345     BESXMLDefaultCommands::terminate( ) ;
00346     BESDEBUG( "standalone", "ServerApp: done terminating default commands"
00347                             << endl ) ;
00348 
00349     BESDEBUG( "standalone", "ServerApp: terminating default module ... "
00350                             << endl ) ;
00351     BESDefaultModule::terminate( ) ;
00352     BESDEBUG( "standalone", "ServerApp: done terminating default module"
00353                             << endl ) ;
00354 
00355     CmdTranslation::terminate( ) ;
00356 
00357     return sig ;
00358 }
00359 
00366 void
00367 StandAloneApp::dump( ostream &strm ) const
00368 {
00369     strm << BESIndent::LMarg << "StandAloneApp::dump - ("
00370                              << (void *)this << ")" << endl ;
00371     BESIndent::Indent() ;
00372     if( _client )
00373     {
00374         strm << BESIndent::LMarg << "client: " << endl ;
00375         BESIndent::Indent() ;
00376         _client->dump( strm ) ;
00377         BESIndent::UnIndent() ;
00378     }
00379     else
00380     {
00381         strm << BESIndent::LMarg << "client: null" << endl ;
00382     }
00383     strm << BESIndent::LMarg << "command: " << _cmd << endl ;
00384     strm << BESIndent::LMarg << "output stream: " << (void *)_outputStrm << endl ;
00385     strm << BESIndent::LMarg << "input stream: " << (void *)_inputStrm << endl ;
00386     strm << BESIndent::LMarg << "created input stream? " << _createdInputStrm << endl ;
00387     BESBaseApp::dump( strm ) ;
00388     BESIndent::UnIndent() ;
00389 }
00390 
00391 int
00392 main( int argc, char **argv )
00393 {
00394     StandAloneApp app ;
00395     return app.main( argc, argv ) ;
00396 }
00397