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() ) ==
00176                     static_cast<int>(inQuestion.length()) )
00177                 {
00178                     toInclude = true ;
00179                 }
00180             }
00181             catch( Error &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_error_message() ;
00187                 throw BESInternalError( serr, __FILE__, __LINE__ ) ;
00188             }
00189         }
00190     }
00191 
00192     if( toInclude == true )
00193     {
00194         if( exclude( inQuestion ) )
00195         {
00196             toInclude = false ;
00197         }
00198     }
00199 
00200     return toInclude ;
00201 }
00202 
00203 bool
00204 BESCatalogUtils::exclude( const string &inQuestion ) const
00205 {
00206     list<string>::const_iterator e_iter = _exclude.begin() ;
00207     list<string>::const_iterator e_end = _exclude.end() ;
00208     for( ; e_iter != e_end; e_iter++ )
00209     {
00210         string reg = *e_iter ;
00211         try
00212         {
00213             Regex reg_expr( reg.c_str() ) ;
00214             if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) ==
00215                 static_cast<int>(inQuestion.length()) )
00216             {
00217                 return true ;
00218             }
00219         }
00220         catch( Error &e )
00221         {
00222             string serr = (string)"Unable to get catalog information, "
00223                           + "malformed Catalog Exclude parameter " 
00224                           + "in bes configuration file around " 
00225                           + reg + ": " + e.get_error_message() ;
00226             throw BESInternalError( serr, __FILE__, __LINE__ ) ;
00227         }
00228     }
00229     return false ;
00230 }
00231 
00232 BESCatalogUtils::match_citer
00233 BESCatalogUtils::match_list_begin() const
00234 {
00235     return _match_list.begin() ;
00236 }
00237 
00238 BESCatalogUtils::match_citer
00239 BESCatalogUtils::match_list_end() const
00240 {
00241     return _match_list.end() ;
00242 }
00243 
00244 void
00245 BESCatalogUtils::dump( ostream &strm ) const
00246 {
00247     strm << BESIndent::LMarg << "BESCatalogUtils::dump - ("
00248                              << (void *)this << ")" << endl ;
00249     BESIndent::Indent() ;
00250 
00251     strm << BESIndent::LMarg << "root directory: " << _root_dir << endl ;
00252 
00253     if( _include.size() )
00254     {
00255         strm << BESIndent::LMarg << "include list:" << endl ;
00256         BESIndent::Indent() ;
00257         list<string>::const_iterator i_iter = _include.begin() ;
00258         list<string>::const_iterator i_end = _include.end() ;
00259         for( ; i_iter != i_end; i_iter++ )
00260         {
00261             strm << BESIndent::LMarg << *i_iter << endl ;
00262         }
00263         BESIndent::UnIndent() ;
00264     }
00265     else
00266     {
00267         strm << BESIndent::LMarg << "include list: empty" << endl ;
00268     }
00269 
00270     if( _exclude.size() )
00271     {
00272         strm << BESIndent::LMarg << "exclude list:" << endl ;
00273         BESIndent::Indent() ;
00274         list<string>::const_iterator e_iter = _exclude.begin() ;
00275         list<string>::const_iterator e_end = _exclude.end() ;
00276         for( ; e_iter != e_end; e_iter++ )
00277         {
00278             strm << BESIndent::LMarg << *e_iter << endl ;
00279         }
00280         BESIndent::UnIndent() ;
00281     }
00282     else
00283     {
00284         strm << BESIndent::LMarg << "exclude list: empty" << endl ;
00285     }
00286 
00287     if( _match_list.size() )
00288     {
00289         strm << BESIndent::LMarg << "type matches:" << endl ;
00290         BESIndent::Indent() ;
00291         BESCatalogUtils::match_citer i = _match_list.begin() ;
00292         BESCatalogUtils::match_citer ie = _match_list.end() ;
00293         for( ; i != ie; i++ )
00294         {
00295             type_reg match = (*i) ;
00296             strm << BESIndent::LMarg << match.type << " : "
00297                                      << match.reg << endl ;
00298         }
00299         BESIndent::UnIndent() ;
00300     }
00301     else
00302     {
00303         strm << BESIndent::LMarg << "    type matches: empty" << endl ;
00304     }
00305 
00306     if( _follow_syms )
00307     {
00308         strm << BESIndent::LMarg << "    follow symbolic links: on" << endl ;
00309     }
00310     else
00311     {
00312         strm << BESIndent::LMarg << "    follow symbolic links: off" << endl ;
00313     }
00314 
00315     BESIndent::UnIndent() ;
00316 }
00317 
00318 const BESCatalogUtils *
00319 BESCatalogUtils::Utils( const string &cat_name )
00320 {
00321     BESCatalogUtils *utils = BESCatalogUtils::_instances[cat_name] ;
00322     if( !utils )
00323     {
00324         utils = new BESCatalogUtils( cat_name );
00325         BESCatalogUtils::_instances[cat_name] = utils ;
00326     }
00327     return utils ;
00328 }
00329 

Generated on Thu Sep 16 15:20:29 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.4.7