00001
00002
00003 #include "sys/types.h"
00004 #include "sys/stat.h"
00005 #include "dirent.h"
00006 #include "stdio.h"
00007
00008 #include "BESCatalogUtils.h"
00009 #include "TheBESKeys.h"
00010 #include "BESException.h"
00011 #include "GNURegex.h"
00012 #include "Error.h"
00013
00014 map<string, BESCatalogUtils *> BESCatalogUtils::_instances ;
00015
00016 BESCatalogUtils::
00017 BESCatalogUtils( const string &n )
00018 {
00019 string key = "BES.Catalog." + n + ".RootDirectory" ;
00020 bool found = false ;
00021 _root_dir = TheBESKeys::TheKeys()->get_key( key, found ) ;
00022 if( !found || _root_dir == "" )
00023 {
00024 string s = key + " not defined in key file" ;
00025 throw BESException( s, __FILE__, __LINE__ ) ;
00026 }
00027 DIR *dip = opendir( _root_dir.c_str() ) ;
00028 if( dip == NULL )
00029 {
00030 string serr = "BESCatalogDirectory - root directory "
00031 + _root_dir + " does not exist" ;
00032 throw BESException( serr, __FILE__, __LINE__ ) ;
00033 }
00034 closedir( dip ) ;
00035
00036 key = (string)"BES.Catalog." + n + ".Exclude" ;
00037 string e_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00038 if( found && e_str != "" && e_str != ";" )
00039 {
00040 build_list( _exclude, e_str ) ;
00041 }
00042
00043 key = (string)"BES.Catalog." + n + ".Include" ;
00044 string i_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00045 if( found && i_str != "" && i_str != ";" )
00046 {
00047 build_list( _include, i_str ) ;
00048 }
00049
00050 key = "BES.Catalog." + n + ".TypeMatch" ;
00051 string curr_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00052 if( curr_str == "" )
00053 {
00054 string s = key + " not defined in key file" ;
00055 throw BESException( s, __FILE__, __LINE__ ) ;
00056 }
00057
00058 string::size_type str_begin = 0 ;
00059 string::size_type str_end = curr_str.length() ;
00060 string::size_type semi = 0 ;
00061 bool done = false ;
00062 while( done == false )
00063 {
00064 semi = curr_str.find( ";", str_begin ) ;
00065 if( semi == string::npos )
00066 {
00067 string s = (string)"Catalog type match malformed, no semicolon, "
00068 "looking for type:regexp;[type:regexp;]" ;
00069 throw BESException( s, __FILE__, __LINE__ ) ;
00070 }
00071 else
00072 {
00073 string a_pair = curr_str.substr( str_begin, semi-str_begin ) ;
00074 str_begin = semi+1 ;
00075 if( semi == str_end-1 )
00076 {
00077 done = true ;
00078 }
00079
00080 string::size_type col = a_pair.find( ":" ) ;
00081 if( col == string::npos )
00082 {
00083 string s = (string)"Catalog type match malformed, no colon, "
00084 + "looking for type:regexp;[type:regexp;]" ;
00085 throw BESException( s, __FILE__, __LINE__ ) ;
00086 }
00087 else
00088 {
00089 type_reg newval ;
00090 newval.type = a_pair.substr( 0, col ) ;
00091 newval.reg = a_pair.substr( col+1, a_pair.length()-col ) ;
00092 _match_list.push_back( newval ) ;
00093 }
00094 }
00095 }
00096 }
00097
00098 void
00099 BESCatalogUtils::build_list( list<string> &theList, const string &listStr )
00100 {
00101 string::size_type str_begin = 0 ;
00102 string::size_type str_end = listStr.length() ;
00103 string::size_type semi = 0 ;
00104 bool done = false ;
00105 while( done == false )
00106 {
00107 semi = listStr.find( ";", str_begin ) ;
00108 if( semi == string::npos )
00109 {
00110 string s = (string)"Catalog type match malformed, no semicolon, "
00111 "looking for type:regexp;[type:regexp;]" ;
00112 throw BESException( s, __FILE__, __LINE__ ) ;
00113 }
00114 else
00115 {
00116 string a_member = listStr.substr( str_begin, semi-str_begin ) ;
00117 str_begin = semi+1 ;
00118 if( semi == str_end-1 )
00119 {
00120 done = true ;
00121 }
00122 if( a_member != "" ) theList.push_back( a_member ) ;
00123 }
00124 }
00125 }
00126
00127 bool
00128 BESCatalogUtils::include( const string &inQuestion ) const
00129 {
00130 bool toInclude = false ;
00131
00132
00133
00134
00135 if( _include.size() == 0 )
00136 {
00137 toInclude = true ;
00138 }
00139 else
00140 {
00141 list<string>::const_iterator i_iter = _include.begin() ;
00142 list<string>::const_iterator i_end = _include.end() ;
00143 for( ; i_iter != i_end; i_iter++ )
00144 {
00145 string reg = *i_iter ;
00146 try
00147 {
00148
00149
00150 Regex reg_expr( reg.c_str() ) ;
00151 if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) == inQuestion.length() )
00152 {
00153 toInclude = true ;
00154 }
00155 }
00156 catch( Error &e )
00157 {
00158 string serr = (string)"Unable to get catalog information, "
00159 + "malformed Catalog Include parameter "
00160 + "in bes configuration file around "
00161 + reg + ": " + e.get_error_message() ;
00162 throw BESException( serr, __FILE__, __LINE__ ) ;
00163 }
00164 }
00165 }
00166
00167 if( toInclude == true )
00168 {
00169 if( exclude( inQuestion ) )
00170 {
00171 toInclude = false ;
00172 }
00173 }
00174
00175 return toInclude ;
00176 }
00177
00178 bool
00179 BESCatalogUtils::exclude( const string &inQuestion ) const
00180 {
00181 list<string>::const_iterator e_iter = _exclude.begin() ;
00182 list<string>::const_iterator e_end = _exclude.end() ;
00183 for( ; e_iter != e_end; e_iter++ )
00184 {
00185 string reg = *e_iter ;
00186 try
00187 {
00188 Regex reg_expr( reg.c_str() ) ;
00189 if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) == inQuestion.length() )
00190 {
00191 return true ;
00192 }
00193 }
00194 catch( Error &e )
00195 {
00196 string serr = (string)"Unable to get catalog information, "
00197 + "malformed Catalog Exclude parameter "
00198 + "in bes configuration file around "
00199 + reg + ": " + e.get_error_message() ;
00200 throw BESException( serr, __FILE__, __LINE__ ) ;
00201 }
00202 }
00203 return false ;
00204 }
00205
00206 BESCatalogUtils::match_citer
00207 BESCatalogUtils::match_list_begin() const
00208 {
00209 return _match_list.begin() ;
00210 }
00211
00212 BESCatalogUtils::match_citer
00213 BESCatalogUtils::match_list_end() const
00214 {
00215 return _match_list.end() ;
00216 }
00217
00218 void
00219 BESCatalogUtils::dump( ostream &strm ) const
00220 {
00221 strm << BESIndent::LMarg << "BESCatalogUtils::dump - ("
00222 << (void *)this << ")" << endl ;
00223 BESIndent::Indent() ;
00224
00225 strm << BESIndent::LMarg << "root directory: " << _root_dir << endl ;
00226
00227 if( _include.size() )
00228 {
00229 strm << BESIndent::LMarg << "include list:" << endl ;
00230 BESIndent::Indent() ;
00231 list<string>::const_iterator i_iter = _include.begin() ;
00232 list<string>::const_iterator i_end = _include.end() ;
00233 for( ; i_iter != i_end; i_iter++ )
00234 {
00235 strm << BESIndent::LMarg << *i_iter << endl ;
00236 }
00237 BESIndent::UnIndent() ;
00238 }
00239 else
00240 {
00241 strm << BESIndent::LMarg << "include list: empty" << endl ;
00242 }
00243
00244 if( _exclude.size() )
00245 {
00246 strm << BESIndent::LMarg << "exclude list:" << endl ;
00247 BESIndent::Indent() ;
00248 list<string>::const_iterator e_iter = _exclude.begin() ;
00249 list<string>::const_iterator e_end = _exclude.end() ;
00250 for( ; e_iter != e_end; e_iter++ )
00251 {
00252 strm << BESIndent::LMarg << *e_iter << endl ;
00253 }
00254 BESIndent::UnIndent() ;
00255 }
00256 else
00257 {
00258 strm << BESIndent::LMarg << "exclude list: empty" << endl ;
00259 }
00260
00261 if( _match_list.size() )
00262 {
00263 strm << BESIndent::LMarg << "type matches:" << endl ;
00264 BESIndent::Indent() ;
00265 BESCatalogUtils::match_citer i = _match_list.begin() ;
00266 BESCatalogUtils::match_citer ie = _match_list.end() ;
00267 for( ; i != ie; i++ )
00268 {
00269 type_reg match = (*i) ;
00270 strm << BESIndent::LMarg << match.type << " : "
00271 << match.reg << endl ;
00272 }
00273 BESIndent::UnIndent() ;
00274 }
00275 else
00276 {
00277 strm << BESIndent::LMarg << " type matches: empty" << endl ;
00278 }
00279
00280 BESIndent::UnIndent() ;
00281 }
00282
00283 const BESCatalogUtils *
00284 BESCatalogUtils::Utils( const string &cat_name )
00285 {
00286 BESCatalogUtils *utils = BESCatalogUtils::_instances[cat_name] ;
00287 if( !utils )
00288 {
00289 utils = new BESCatalogUtils( cat_name );
00290 BESCatalogUtils::_instances[cat_name] = utils ;
00291 }
00292 return utils ;
00293 }
00294