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

Generated on Wed May 12 09:53:07 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.4.7