BESInterface.cc

Go to the documentation of this file.
00001 // BESInterface.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,2005 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 Atmostpheric 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>
00034 #include <string>
00035 #include <sstream>
00036 
00037 using std::string;
00038 using std::ostringstream;
00039 using std::bad_alloc;
00040 
00041 #include "BESInterface.h"
00042 
00043 #include "BESStatusReturn.h"
00044 #include "TheBESKeys.h"
00045 #include "BESResponseHandler.h"
00046 #include "BESAggFactory.h"
00047 #include "BESAggregationServer.h"
00048 #include "BESReporterList.h"
00049 
00050 #include "BESExceptionManager.h"
00051 #include "BESHandlerException.h"
00052 #include "BESMemoryException.h"
00053 #include "BESAggregationException.h"
00054 
00055 #include "BESDataNames.h"
00056 
00057 #include "BESDebug.h"
00058 #include "BESTransmitException.h"
00059 
00060 list < p_bes_init > BESInterface::_init_list;
00061 list < p_bes_end > BESInterface::_end_list;
00062 
00063 BESInterface::BESInterface()
00064 :  _transmitter(0)
00065 {
00066 }
00067 
00068 BESInterface::~BESInterface()
00069 {
00070 }
00071 
00099 int
00100  BESInterface::execute_request()
00101 {
00102     int status = 0;
00103 
00104     try {
00105         initialize();
00106         validate_data_request();
00107         build_data_request_plan();
00108         execute_data_request_plan();
00109         invoke_aggregation();
00110     }
00111     catch(BESException & ex) {
00112         status = exception_manager(ex);
00113     }
00114     catch(bad_alloc & b) {
00115         string serr = "BES out of memory";
00116         BESMemoryException ex(serr, __FILE__, __LINE__);
00117         status = exception_manager(ex);
00118     }
00119     catch(...) {
00120         string serr = "An undefined exception has been thrown";
00121         BESException ex(serr, __FILE__, __LINE__);
00122         status = exception_manager(ex);
00123     }
00124 
00125     try {
00126         transmit_data();
00127         log_status();
00128         report_request();
00129         end_request();
00130         if (_dhi.error_info)
00131             delete _dhi.error_info;
00132         _dhi.error_info = 0;
00133     }
00134     catch(BESException & ex) {
00135         status = exception_manager(ex);
00136     }
00137     catch(bad_alloc & b) {
00138         string serr = "BES out of memory";
00139         BESMemoryException ex(serr, __FILE__, __LINE__);
00140         status = exception_manager(ex);
00141     }
00142     catch(...) {
00143         string serr = "An undefined exception has been thrown";
00144         BESException ex(serr, __FILE__, __LINE__);
00145         status = exception_manager(ex);
00146     }
00147 
00148     // If there is error information then the transmit, log, report or end
00149     // failed, so just print the error information
00150     if (_dhi.error_info) {
00151         _dhi.error_info->print(stdout);
00152     }
00153 
00154     return status;
00155 }
00156 
00157 void BESInterface::add_init_callback(p_bes_init init)
00158 {
00159     _init_list.push_back(init);
00160 }
00161 
00167 void BESInterface::initialize()
00168 {
00169     BESDEBUG("Initializing request: " << _dhi.data[DATA_REQUEST] << " ... ")
00170     bool do_continue = true;
00171     init_iter i = _init_list.begin();
00172     
00173     for (; i != _init_list.end() && do_continue == true; i++) {
00174         p_bes_init p = *i;
00175         do_continue = p(_dhi);
00176     }
00177     
00178     if (!do_continue) {
00179         BESDEBUG("FAILED" << endl)
00180         string se = "Initialization callback failed, exiting";
00181         throw BESException(se, __FILE__, __LINE__);
00182     } else {
00183         BESDEBUG("OK" << endl)
00184     }
00185 }
00186 
00189 void BESInterface::validate_data_request()
00190 {
00191 }
00192 
00201 void BESInterface::build_data_request_plan()
00202 {
00203 }
00204 
00218 void BESInterface::execute_data_request_plan()
00219 {
00220     BESDEBUG("Executing request: " << _dhi.data[DATA_REQUEST] << " ... ")
00221     BESResponseHandler *rh = _dhi.response_handler;
00222     if (rh) {
00223         rh->execute(_dhi);
00224     } else {
00225         BESDEBUG("FAILED" << endl)
00226         string se = "The response handler \"" + _dhi.action
00227             + "\" does not exist";
00228         throw BESHandlerException(se, __FILE__, __LINE__);
00229     }
00230     BESDEBUG("OK" << endl)
00231 }
00232 
00235 void BESInterface::invoke_aggregation()
00236 {
00237     if (_dhi.data[AGG_CMD] != "") {
00238         BESDEBUG("aggregating with: " << _dhi.data[AGG_CMD] << " ... ")
00239         BESAggregationServer *agg =
00240             BESAggFactory::TheFactory()->find_handler(_dhi.
00241                                                       data[AGG_HANDLER]);
00242         if (agg) {
00243             agg->aggregate(_dhi);
00244         } else {
00245             BESDEBUG("FAILED" << endl)
00246             string se = "The aggregation handler " + _dhi.data[AGG_HANDLER]
00247                 + "does not exist";
00248             throw BESAggregationException(se, __FILE__, __LINE__);
00249         }
00250         BESDEBUG("OK" << endl)
00251     }
00252 }
00253 
00267 void BESInterface::transmit_data()
00268 {
00269     BESDEBUG("Transmitting request: " << _dhi.data[DATA_REQUEST] << endl)
00270     if (_transmitter) {
00271         if (_dhi.error_info) {
00272             BESDEBUG( "  transmitting error info using transmitter ... " )
00273             _dhi.error_info->transmit(_transmitter, _dhi);
00274         } else if (_dhi.response_handler) {
00275             BESDEBUG( "  transmitting response using transmitter ... " )
00276             _dhi.response_handler->transmit(_transmitter, _dhi);
00277         }
00278     } else {
00279         if (_dhi.error_info) {
00280             BESDEBUG( "  transmitting error info using stdout ... " )
00281             _dhi.error_info->print(stdout);
00282         } else {
00283             BESDEBUG( "  Unable to transmit the response ... FAILED " )
00284             string err = "Unable to transmit the response, no transmitter" ;
00285             throw BESTransmitException( err, __FILE__, __LINE__ ) ;
00286         }
00287     }
00288     BESDEBUG("OK" << endl)
00289 }
00290 
00293 void BESInterface::log_status()
00294 {
00295 }
00296 
00308 void BESInterface::report_request()
00309 {
00310     BESDEBUG("Reporting on request: " << _dhi.
00311              data[DATA_REQUEST] << " ... ")
00312         BESReporterList::TheList()->report(_dhi);
00313     BESDEBUG("OK" << endl)
00314 }
00315 
00316 void BESInterface::add_end_callback(p_bes_end end)
00317 {
00318     _end_list.push_back(end);
00319 }
00320 
00326 void BESInterface::end_request()
00327 {
00328     BESDEBUG("Ending request: " << _dhi.data[DATA_REQUEST] << " ... ")
00329     end_iter i = _end_list.begin();
00330     for (; i != _end_list.end(); i++) {
00331         p_bes_end p = *i;
00332         p(_dhi);
00333     }
00334     BESDEBUG("OK" << endl)
00335 }
00336 
00339 void BESInterface::clean()
00340 {
00341     if (_dhi.response_handler)
00342         delete _dhi.response_handler;
00343     _dhi.response_handler = 0;
00344 }
00345 
00358 int BESInterface::exception_manager(BESException & e)
00359 {
00360     return BESExceptionManager::TheEHM()->handle_exception(e, _dhi);
00361 }
00362 
00371 void BESInterface::dump(ostream & strm) const
00372 {
00373     strm << BESIndent::LMarg << "BESInterface::dump - ("
00374         << (void *) this << ")" << endl;
00375     BESIndent::Indent();
00376 
00377     if (_init_list.size()) {
00378         strm << BESIndent::LMarg << "termination functions:" << endl;
00379         BESIndent::Indent();
00380         init_iter i = _init_list.begin();
00381         for (; i != _init_list.end(); i++) {
00382             strm << BESIndent::LMarg << (void *) (*i) << endl;
00383         }
00384         BESIndent::UnIndent();
00385     } else {
00386         strm << BESIndent::LMarg << "termination functions: none" << endl;
00387     }
00388 
00389     if (_end_list.size()) {
00390         strm << BESIndent::LMarg << "termination functions:" << endl;
00391         BESIndent::Indent();
00392         end_iter i = _end_list.begin();
00393         for (; i != _end_list.end(); i++) {
00394             strm << BESIndent::LMarg << (void *) (*i) << endl;
00395         }
00396         BESIndent::UnIndent();
00397     } else {
00398         strm << BESIndent::LMarg << "termination functions: none" << endl;
00399     }
00400 
00401     strm << BESIndent::LMarg << "data handler interface:" << endl;
00402     BESIndent::Indent();
00403     _dhi.dump(strm);
00404     BESIndent::UnIndent();
00405 
00406     if (_transmitter) {
00407         strm << BESIndent::LMarg << "transmitter:" << endl;
00408         BESIndent::Indent();
00409         _transmitter->dump(strm);
00410         BESIndent::UnIndent();
00411     } else {
00412         strm << BESIndent::LMarg << "transmitter: not set" << endl;
00413     }
00414     BESIndent::UnIndent();
00415 }

Generated on Wed Aug 29 02:59:01 2007 for OPeNDAP Back End Server (BES) by  doxygen 1.5.2