BESCatalogUtils.cc

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

Generated on Sat Aug 22 06:06:21 2009 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.6.0