OPeNDAP Hyrax Back End Server (BES) Updated for version 3.8.3
|
00001 // BESDapTransmit.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 <sstream> 00034 00035 using std::ostringstream; 00036 00037 #include "BESDapTransmit.h" 00038 #include "DODSFilter.h" 00039 #include "BESContainer.h" 00040 #include "BESDapNames.h" 00041 #include "BESDataNames.h" 00042 #include "BESResponseNames.h" 00043 #include "mime_util.h" 00044 #include "BESDASResponse.h" 00045 #include "BESDDSResponse.h" 00046 #include "BESDataDDSResponse.h" 00047 #include "BESContextManager.h" 00048 #include "BESDapError.h" 00049 #include "BESInternalFatalError.h" 00050 #include "BESDebug.h" 00051 #include "Error.h" 00052 00054 // Local Helpers 00055 00056 // File local helper superclass for common exception handling 00057 // for transmitting DAP responses. 00058 class Sender 00059 { 00060 public: 00061 virtual ~Sender() {} 00062 00063 // The main call, non-virtual to force exception handling. 00064 // Subclasses will override send_internal private virtual. 00065 void send(BESResponseObject* obj, BESDataHandlerInterface & dhi) 00066 { 00067 string response_string = get_request_type(); 00068 try 00069 { 00070 send_internal(obj, dhi); 00071 } 00072 catch( InternalErr &e ) 00073 { 00074 string err = "libdap error transmitting " + 00075 response_string + ": " + 00076 e.get_error_message() ; 00077 throw BESDapError( err, true, e.get_error_code(), __FILE__, __LINE__ ) ; 00078 } 00079 catch( Error &e ) 00080 { 00081 string err = "libdap error transmitting " + 00082 response_string + ": " + 00083 e.get_error_message() ; 00084 throw BESDapError( err, false, e.get_error_code(), __FILE__, __LINE__ ); 00085 } 00086 catch( const BESError &e ) 00087 { 00088 throw; // rethrow as is 00089 } 00090 catch( const std::exception &e ) 00091 { 00092 string msg("std::exception caught transmitting " + 00093 response_string + ": " + 00094 e.what() ); 00095 throw BESInternalFatalError(msg, __FILE__, __LINE__); 00096 } 00097 catch(...) 00098 { 00099 string s = "unknown error caught transmitting " + 00100 response_string + ": "; 00101 BESInternalFatalError ex( s, __FILE__, __LINE__ ) ; 00102 throw ex; 00103 } 00104 } 00105 00106 // common code for subclasses 00107 bool get_print_mime() const 00108 { 00109 bool found = false ; 00110 string context = "transmit_protocol" ; 00111 string protocol = BESContextManager::TheManager()->get_context( context, 00112 found ) ; 00113 bool print_mime = false ; 00114 if( protocol == "HTTP" ) { 00115 print_mime = true; 00116 } 00117 return print_mime; 00118 } 00119 00120 private: 00121 00122 // Name of the request being sent, for debug 00123 virtual string get_request_type() const = 0; 00124 00125 // Subclasses impl this for specialized behavior 00126 virtual void send_internal( 00127 BESResponseObject * obj, 00128 BESDataHandlerInterface & dhi) = 0; 00129 }; 00130 00131 class SendDAS : public Sender 00132 { 00133 private: 00134 virtual string get_request_type() const { return "DAS"; } 00135 virtual void send_internal( 00136 BESResponseObject * obj, 00137 BESDataHandlerInterface & dhi) 00138 { 00139 BESDASResponse *bdas = dynamic_cast < BESDASResponse * >(obj); 00140 if( !bdas ) { 00141 throw BESInternalError( "cast error", __FILE__, __LINE__ ) ; 00142 } 00143 DAS *das = bdas->get_das(); 00144 dhi.first_container(); 00145 bool print_mime = get_print_mime(); 00146 00147 DODSFilter df ; 00148 df.set_dataset_name( dhi.container->get_real_name() ) ; 00149 df.send_das( dhi.get_output_stream(), *das, "", print_mime ) ; 00150 } 00151 }; 00152 00153 class SendDDS : public Sender 00154 { 00155 private: 00156 virtual string get_request_type() const { return "DDS"; } 00157 virtual void send_internal( 00158 BESResponseObject * obj, 00159 BESDataHandlerInterface & dhi) 00160 { 00161 BESDDSResponse *bdds = dynamic_cast < BESDDSResponse * >(obj); 00162 if( !bdds ) { 00163 throw BESInternalError( "cast error", __FILE__, __LINE__ ) ; 00164 } 00165 DDS *dds = bdds->get_dds(); 00166 ConstraintEvaluator & ce = bdds->get_ce(); 00167 dhi.first_container(); 00168 bool print_mime = get_print_mime(); 00169 00170 DODSFilter df; 00171 df.set_dataset_name(dhi.container->get_real_name()); 00172 df.set_ce(dhi.data[POST_CONSTRAINT]); 00173 df.send_dds(dhi.get_output_stream(), *dds, ce, true, "", print_mime); 00174 } 00175 }; 00176 00177 class SendDataDDS : public Sender 00178 { 00179 private: 00180 virtual string get_request_type() const { return "DataDDS"; } 00181 virtual void send_internal( 00182 BESResponseObject * obj, 00183 BESDataHandlerInterface & dhi) 00184 { 00185 BESDataDDSResponse *bdds = dynamic_cast < BESDataDDSResponse * >(obj); 00186 if( !bdds ) { 00187 throw BESInternalError( "cast error", __FILE__, __LINE__ ) ; 00188 } 00189 DataDDS *dds = bdds->get_dds(); 00190 ConstraintEvaluator & ce = bdds->get_ce(); 00191 dhi.first_container(); 00192 bool print_mime = get_print_mime(); 00193 00194 DODSFilter df; 00195 df.set_dataset_name(dds->filename()); 00196 df.set_ce(dhi.data[POST_CONSTRAINT]); 00197 df.send_data(*dds, ce, dhi.get_output_stream(), "", print_mime); 00198 } 00199 }; 00200 00201 class SendDDX : public Sender 00202 { 00203 private: 00204 virtual string get_request_type() const { return "DDX"; } 00205 virtual void send_internal( 00206 BESResponseObject * obj, 00207 BESDataHandlerInterface & dhi) 00208 { 00209 BESDDSResponse *bdds = dynamic_cast < BESDDSResponse * >(obj); 00210 if( !bdds ) { 00211 throw BESInternalError( "cast error", __FILE__, __LINE__ ) ; 00212 } 00213 DDS *dds = bdds->get_dds(); 00214 ConstraintEvaluator & ce = bdds->get_ce(); 00215 dhi.first_container(); 00216 bool print_mime = get_print_mime(); 00217 00218 DODSFilter df; 00219 df.set_dataset_name(dhi.container->get_real_name()); 00220 df.set_ce(dhi.data[POST_CONSTRAINT]); 00221 df.send_ddx(*dds, ce, dhi.get_output_stream(), print_mime); 00222 } 00223 }; 00224 00225 class SendDataDDX : public Sender 00226 { 00227 private: 00228 virtual string get_request_type() const { return "DataDDX"; } 00229 virtual void send_internal( 00230 BESResponseObject * obj, 00231 BESDataHandlerInterface & dhi) 00232 { 00233 BESDataDDSResponse *bdds = dynamic_cast < BESDataDDSResponse * >(obj); 00234 if( !bdds ) { 00235 throw BESInternalError( "cast error", __FILE__, __LINE__ ) ; 00236 } 00237 DataDDS *dds = bdds->get_dds(); 00238 ConstraintEvaluator & ce = bdds->get_ce(); 00239 dhi.first_container(); 00240 bool print_mime = get_print_mime(); 00241 00242 DODSFilter df; 00243 df.set_dataset_name(dds->filename()); 00244 df.set_ce(dhi.data[POST_CONSTRAINT]); 00245 BESDEBUG("dap", "dhi.data[DATADDX_STARTID]: " << dhi.data[DATADDX_STARTID] << endl); 00246 df.send_data_ddx(*dds, ce, dhi.get_output_stream(), 00247 dhi.data[DATADDX_STARTID], dhi.data[DATADDX_BOUNDARY], 00248 "", print_mime); 00249 } 00250 }; 00251 00253 // Public Interface Impl 00254 00255 BESDapTransmit::BESDapTransmit() 00256 : BESBasicTransmitter() 00257 { 00258 add_method( DAS_SERVICE, BESDapTransmit::send_basic_das ) ; 00259 add_method( DDS_SERVICE, BESDapTransmit::send_basic_dds ) ; 00260 add_method( DDX_SERVICE, BESDapTransmit::send_basic_ddx ) ; 00261 add_method( DATA_SERVICE, BESDapTransmit::send_basic_data ) ; 00262 add_method( DATADDX_SERVICE, BESDapTransmit::send_basic_dataddx ) ; 00263 } 00264 00265 void 00266 BESDapTransmit::send_basic_das(BESResponseObject * obj, 00267 BESDataHandlerInterface & dhi) 00268 { 00269 SendDAS sender; 00270 sender.send(obj, dhi); 00271 } 00272 00273 void 00274 BESDapTransmit::send_basic_dds(BESResponseObject * obj, 00275 BESDataHandlerInterface & dhi) 00276 { 00277 SendDDS sender; 00278 sender.send(obj, dhi); 00279 } 00280 00281 void 00282 BESDapTransmit::send_basic_ddx(BESResponseObject * obj, 00283 BESDataHandlerInterface & dhi) 00284 { 00285 SendDDX sender; 00286 sender.send(obj, dhi); 00287 } 00288 00289 void 00290 BESDapTransmit::send_basic_data(BESResponseObject * obj, 00291 BESDataHandlerInterface & dhi) 00292 { 00293 SendDataDDS sender; 00294 sender.send(obj, dhi); 00295 } 00296 00297 void 00298 BESDapTransmit::send_basic_dataddx(BESResponseObject * obj, 00299 BESDataHandlerInterface & dhi) 00300 { 00301 SendDataDDX sender; 00302 sender.send(obj, dhi); 00303 }