OPeNDAP Hyrax Back End Server (BES)
Updated for version 3.8.3
|
00001 // BESCatalogUtils.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 "config.h" 00034 00035 #include <sys/types.h> 00036 #include <sys/stat.h> 00037 #include <dirent.h> 00038 00039 #include <iostream> 00040 using std::cout ; 00041 using std::endl ; 00042 00043 #include "BESCatalogUtils.h" 00044 #include "TheBESKeys.h" 00045 #include "BESInternalError.h" 00046 #include "BESSyntaxUserError.h" 00047 #include "BESNotFoundError.h" 00048 #include "BESRegex.h" 00049 #include "BESUtil.h" 00050 00051 map<string, BESCatalogUtils *> BESCatalogUtils::_instances ; 00052 00053 BESCatalogUtils:: 00054 BESCatalogUtils( const string &n ) 00055 : _follow_syms( false ) 00056 { 00057 string key = "BES.Catalog." + n + ".RootDirectory" ; 00058 bool found = false ; 00059 TheBESKeys::TheKeys()->get_value( key, _root_dir, found ) ; 00060 if( !found || _root_dir == "" ) 00061 { 00062 string s = key + " not defined in BES configuration file" ; 00063 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ; 00064 } 00065 DIR *dip = opendir( _root_dir.c_str() ) ; 00066 if( dip == NULL ) 00067 { 00068 string serr = "BESCatalogDirectory - root directory " 00069 + _root_dir + " does not exist" ; 00070 throw BESNotFoundError( serr, __FILE__, __LINE__ ) ; 00071 } 00072 closedir( dip ) ; 00073 00074 found = false ; 00075 key = (string)"BES.Catalog." + n + ".Exclude" ; 00076 vector<string> vals ; 00077 TheBESKeys::TheKeys()->get_values( key, vals, found ) ; 00078 vector<string>::iterator ei = vals.begin() ; 00079 vector<string>::iterator ee = vals.end() ; 00080 for( ; ei != ee; ei++ ) 00081 { 00082 string e_str = (*ei) ; 00083 if( !e_str.empty() && e_str != ";" ) 00084 BESUtil::explode( ';', e_str, _exclude ) ; 00085 } 00086 00087 key = (string)"BES.Catalog." + n + ".Include" ; 00088 vals.clear() ; 00089 TheBESKeys::TheKeys()->get_values( key, vals, found ) ; 00090 vector<string>::iterator ii = vals.begin() ; 00091 vector<string>::iterator ie = vals.end() ; 00092 for( ; ii != ie; ii++ ) 00093 { 00094 string i_str = (*ii) ; 00095 if( !i_str.empty() && i_str != ";" ) 00096 BESUtil::explode( ';', i_str, _include ) ; 00097 } 00098 00099 key = "BES.Catalog." + n + ".TypeMatch" ; 00100 list<string> match_list ; 00101 vals.clear() ; 00102 TheBESKeys::TheKeys()->get_values( key, vals, found ) ; 00103 if( !found || vals.size() == 0 ) 00104 { 00105 string s = key + " not defined in key file" ; 00106 throw BESInternalError( s, __FILE__, __LINE__ ) ; 00107 } 00108 vector<string>::iterator vi = vals.begin() ; 00109 vector<string>::iterator ve = vals.end() ; 00110 for( ; vi != ve; vi++ ) 00111 { 00112 BESUtil::explode( ';', (*vi), match_list ) ; 00113 } 00114 00115 list<string>::iterator mli = match_list.begin() ; 00116 list<string>::iterator mle = match_list.end() ; 00117 for( ; mli != mle; mli++ ) 00118 { 00119 if( !((*mli).empty()) && *(mli) != ";" ) 00120 { 00121 list<string> amatch ; 00122 BESUtil::explode( ':', (*mli), amatch ) ; 00123 if( amatch.size() != 2 ) 00124 { 00125 string s = (string)"Catalog type match malformed, " 00126 + "looking for type:regexp;[type:regexp;]" ; 00127 throw BESInternalError( s, __FILE__, __LINE__ ) ; 00128 } 00129 list<string>::iterator ami = amatch.begin() ; 00130 type_reg newval ; 00131 newval.type = (*ami) ; 00132 ami++ ; 00133 newval.reg = (*ami) ; 00134 _match_list.push_back( newval ) ; 00135 } 00136 } 00137 00138 key = (string)"BES.Catalog." + n + ".FollowSymLinks" ; 00139 string s_str ; 00140 TheBESKeys::TheKeys()->get_value( key, s_str, found ) ; 00141 s_str = BESUtil::lowercase( s_str ) ; 00142 if( s_str == "yes" || s_str == "on" || s_str == "true" ) 00143 { 00144 _follow_syms = true ; 00145 } 00146 } 00147 00148 bool 00149 BESCatalogUtils::include( const string &inQuestion ) const 00150 { 00151 bool toInclude = false ; 00152 00153 // First check the file against the include list. If the file should be 00154 // included then check the exclude list to see if there are exceptions 00155 // to the include list. 00156 if( _include.size() == 0 ) 00157 { 00158 toInclude = true ; 00159 } 00160 else 00161 { 00162 list<string>::const_iterator i_iter = _include.begin() ; 00163 list<string>::const_iterator i_end = _include.end() ; 00164 for( ; i_iter != i_end; i_iter++ ) 00165 { 00166 string reg = *i_iter ; 00167 if( !reg.empty() ) 00168 { 00169 try 00170 { 00171 // must match exactly, meaing result is = to length of string 00172 // in question 00173 BESRegex reg_expr( reg.c_str() ) ; 00174 if( reg_expr.match( inQuestion.c_str(), 00175 inQuestion.length() ) == 00176 static_cast<int>(inQuestion.length()) ) 00177 { 00178 toInclude = true ; 00179 } 00180 } 00181 catch( BESError &e ) 00182 { 00183 string serr = (string)"Unable to get catalog information, " 00184 + "malformed Catalog Include parameter " 00185 + "in bes configuration file around " 00186 + reg + ": " + e.get_message() ; 00187 throw BESInternalError( serr, __FILE__, __LINE__ ) ; 00188 } 00189 } 00190 } 00191 } 00192 00193 if( toInclude == true ) 00194 { 00195 if( exclude( inQuestion ) ) 00196 { 00197 toInclude = false ; 00198 } 00199 } 00200 00201 return toInclude ; 00202 } 00203 00204 bool 00205 BESCatalogUtils::exclude( const string &inQuestion ) const 00206 { 00207 list<string>::const_iterator e_iter = _exclude.begin() ; 00208 list<string>::const_iterator e_end = _exclude.end() ; 00209 for( ; e_iter != e_end; e_iter++ ) 00210 { 00211 string reg = *e_iter ; 00212 if( !reg.empty() ) 00213 { 00214 try 00215 { 00216 BESRegex reg_expr( reg.c_str() ) ; 00217 if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) == 00218 static_cast<int>(inQuestion.length()) ) 00219 { 00220 return true ; 00221 } 00222 } 00223 catch( BESError &e ) 00224 { 00225 string serr = (string)"Unable to get catalog information, " 00226 + "malformed Catalog Exclude parameter " 00227 + "in bes configuration file around " 00228 + reg + ": " + e.get_message() ; 00229 throw BESInternalError( serr, __FILE__, __LINE__ ) ; 00230 } 00231 } 00232 } 00233 return false ; 00234 } 00235 00236 BESCatalogUtils::match_citer 00237 BESCatalogUtils::match_list_begin() const 00238 { 00239 return _match_list.begin() ; 00240 } 00241 00242 BESCatalogUtils::match_citer 00243 BESCatalogUtils::match_list_end() const 00244 { 00245 return _match_list.end() ; 00246 } 00247 00248 void 00249 BESCatalogUtils::dump( ostream &strm ) const 00250 { 00251 strm << BESIndent::LMarg << "BESCatalogUtils::dump - (" 00252 << (void *)this << ")" << endl ; 00253 BESIndent::Indent() ; 00254 00255 strm << BESIndent::LMarg << "root directory: " << _root_dir << endl ; 00256 00257 if( _include.size() ) 00258 { 00259 strm << BESIndent::LMarg << "include list:" << endl ; 00260 BESIndent::Indent() ; 00261 list<string>::const_iterator i_iter = _include.begin() ; 00262 list<string>::const_iterator i_end = _include.end() ; 00263 for( ; i_iter != i_end; i_iter++ ) 00264 { 00265 if( !(*i_iter).empty() ) 00266 { 00267 strm << BESIndent::LMarg << *i_iter << endl ; 00268 } 00269 } 00270 BESIndent::UnIndent() ; 00271 } 00272 else 00273 { 00274 strm << BESIndent::LMarg << "include list: empty" << endl ; 00275 } 00276 00277 if( _exclude.size() ) 00278 { 00279 strm << BESIndent::LMarg << "exclude list:" << endl ; 00280 BESIndent::Indent() ; 00281 list<string>::const_iterator e_iter = _exclude.begin() ; 00282 list<string>::const_iterator e_end = _exclude.end() ; 00283 for( ; e_iter != e_end; e_iter++ ) 00284 { 00285 if( !(*e_iter).empty() ) 00286 { 00287 strm << BESIndent::LMarg << *e_iter << endl ; 00288 } 00289 } 00290 BESIndent::UnIndent() ; 00291 } 00292 else 00293 { 00294 strm << BESIndent::LMarg << "exclude list: empty" << endl ; 00295 } 00296 00297 if( _match_list.size() ) 00298 { 00299 strm << BESIndent::LMarg << "type matches:" << endl ; 00300 BESIndent::Indent() ; 00301 BESCatalogUtils::match_citer i = _match_list.begin() ; 00302 BESCatalogUtils::match_citer ie = _match_list.end() ; 00303 for( ; i != ie; i++ ) 00304 { 00305 type_reg match = (*i) ; 00306 strm << BESIndent::LMarg << match.type << " : " 00307 << match.reg << endl ; 00308 } 00309 BESIndent::UnIndent() ; 00310 } 00311 else 00312 { 00313 strm << BESIndent::LMarg << " type matches: empty" << endl ; 00314 } 00315 00316 if( _follow_syms ) 00317 { 00318 strm << BESIndent::LMarg << " follow symbolic links: on" << endl ; 00319 } 00320 else 00321 { 00322 strm << BESIndent::LMarg << " follow symbolic links: off" << endl ; 00323 } 00324 00325 BESIndent::UnIndent() ; 00326 } 00327 00328 const BESCatalogUtils * 00329 BESCatalogUtils::Utils( const string &cat_name ) 00330 { 00331 BESCatalogUtils *utils = BESCatalogUtils::_instances[cat_name] ; 00332 if( !utils ) 00333 { 00334 utils = new BESCatalogUtils( cat_name ); 00335 BESCatalogUtils::_instances[cat_name] = utils ; 00336 } 00337 return utils ; 00338 } 00339