OPeNDAP Hyrax Back End Server (BES)
Updated for version 3.8.3
|
00001 // BESXMLGetCommand.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 "BESXMLGetCommand.h" 00034 #include "BESDefinitionStorageList.h" 00035 #include "BESDefinitionStorage.h" 00036 #include "BESDefine.h" 00037 #include "BESDataNames.h" 00038 #include "BESResponseNames.h" 00039 #include "BESDapNames.h" 00040 #include "BESXMLUtils.h" 00041 #include "BESUtil.h" 00042 #include "BESSyntaxUserError.h" 00043 #include "BESDebug.h" 00044 00045 BESXMLGetCommand::BESXMLGetCommand( const BESDataHandlerInterface &base_dhi ) 00046 : BESXMLCommand( base_dhi ), _sub_cmd( 0 ) 00047 { 00048 } 00049 00056 void 00057 BESXMLGetCommand::parse_request( xmlNode *node ) 00058 { 00059 string name ; 00060 string value ; 00061 map<string, string> props ; 00062 BESXMLUtils::GetNodeInfo( node, name, value, props ) ; 00063 if( name != GET_RESPONSE ) 00064 { 00065 string err = "The specified command " + name 00066 + " is not a get command" ; 00067 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ; 00068 } 00069 00070 // grab the type first and check to see if there is a registered command 00071 // to handle get.<type> requests 00072 string type = props["type"] ; 00073 if( type.empty() ) 00074 { 00075 string err = name + " command: Must specify data product type" ; 00076 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ; 00077 } 00078 string new_cmd = (string)GET_RESPONSE + "." + type ; 00079 p_xmlcmd_builder bldr = BESXMLCommand::find_command( new_cmd ) ; 00080 if( bldr ) 00081 { 00082 // the base dhi was copied to this instance's _dhi variable. 00083 _sub_cmd = bldr( _dhi ) ; 00084 if( !_sub_cmd ) 00085 { 00086 string err = (string)"Failed to build command object for " 00087 + new_cmd ; 00088 throw BESInternalError( err, __FILE__, __LINE__ ) ; 00089 } 00090 00091 // parse the request given the current node 00092 _sub_cmd->parse_request( node ) ; 00093 00094 // return from this sub command 00095 return ; 00096 } 00097 00098 parse_basic_get( node, name, type, value, props ) ; 00099 _str_cmd += ";" ; 00100 00101 // now that we've set the action, go get the response handler for the 00102 // action 00103 BESXMLCommand::set_response() ; 00104 } 00105 00106 void 00107 BESXMLGetCommand::parse_basic_get( xmlNode *node, 00108 const string &name, 00109 const string &type, 00110 const string &value, 00111 map<string,string> &props ) 00112 { 00113 _str_cmd = (string)"get " + type ; 00114 00115 _definition = props["definition"] ; 00116 if( _definition.empty() ) 00117 { 00118 string err = name + " command: Must specify definition" ; 00119 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ; 00120 } 00121 _str_cmd += " for " + _definition ; 00122 00123 string returnAs = props["returnAs"] ; 00124 if( returnAs.empty() ) 00125 { 00126 returnAs = DAP2_FORMAT ; 00127 } 00128 _dhi.data[RETURN_CMD] = returnAs ; 00129 00130 _str_cmd += " return as " + returnAs ; 00131 00132 _dhi.action = "get." ; 00133 _dhi.action += BESUtil::lowercase( type ) ; 00134 BESDEBUG( "besxml", "Converted xml element name to command " 00135 << _dhi.action << endl ) ; 00136 } 00137 00144 BESDataHandlerInterface & 00145 BESXMLGetCommand::get_dhi() 00146 { 00147 if( _sub_cmd ) return _sub_cmd->get_dhi() ; 00148 00149 return _dhi ; 00150 } 00151 00159 void 00160 BESXMLGetCommand::prep_request() 00161 { 00162 // if there is a sub command then execute the prep request on it 00163 if( _sub_cmd ) 00164 { 00165 _sub_cmd->prep_request() ; 00166 return ; 00167 } 00168 00169 // FIX: should this be using dot notation? Like get das for volatile.d ; 00170 // Or do it like the containers, just find the first one available? Same 00171 // question for containers then? 00172 BESDefine *d = BESDefinitionStorageList::TheList()->look_for( _definition ); 00173 if( !d ) 00174 { 00175 string s = (string)"Unable to find definition " + _definition ; 00176 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ; 00177 } 00178 00179 BESDefine::containers_citer i = d->first_container() ; 00180 BESDefine::containers_citer ie = d->end_container() ; 00181 while( i != ie ) 00182 { 00183 _dhi.containers.push_back( *i ) ; 00184 i++ ; 00185 } 00186 _dhi.data[AGG_CMD] = d->get_agg_cmd() ; 00187 _dhi.data[AGG_HANDLER] = d->get_agg_handler() ; 00188 00189 } 00190 00197 void 00198 BESXMLGetCommand::dump( ostream &strm ) const 00199 { 00200 strm << BESIndent::LMarg << "BESXMLGetCommand::dump - (" 00201 << (void *)this << ")" << endl ; 00202 BESIndent::Indent() ; 00203 BESXMLCommand::dump( strm ) ; 00204 BESIndent::UnIndent() ; 00205 } 00206 00207 BESXMLCommand * 00208 BESXMLGetCommand::CommandBuilder( const BESDataHandlerInterface &base_dhi ) 00209 { 00210 return new BESXMLGetCommand( base_dhi ) ; 00211 } 00212