Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

PathResolver.cpp

Go to the documentation of this file.
00001 #include "GaudiKernel/PathResolver.h"
00002 
00003 #include <iostream>
00004 #include <string>
00005 #include <vector>
00006 #include <stdlib.h>
00007 
00008 #include <boost/algorithm/string/split.hpp>
00009 #include <boost/algorithm/string/classification.hpp>
00010 #include <boost/filesystem.hpp>
00011 
00012 namespace bf = boost::filesystem;
00013 using namespace std;
00014 
00015 #ifdef _WIN32
00016   static const char* path_separator = ",;";
00017 #else
00018   static const char* path_separator = ",:";
00019 #endif
00020 
00021 //
00023 //
00024 
00025 namespace System {
00026 
00027 typedef enum {
00028   PR_regular_file,
00029   PR_directory
00030 } PR_file_type;
00031 
00032 typedef enum {
00033   PR_local,
00034   PR_recursive
00035 } PR_search_type;
00036 
00037 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00038 
00039 static bool
00040 PR_find( const bf::path& file, const string& search_list,
00041          PR_file_type file_type, PathResolver::SearchType search_type,
00042          string& result ) {
00043 
00044   bool found(false);
00045 
00046   // look for file as specified first
00047 
00048   try {
00049     if ( ( file_type == PR_regular_file && is_regular_file( file ) ) ||
00050          ( file_type == PR_directory && is_directory( file ) ) ) {
00051       result = bf::complete(file).string();
00052       return true;
00053     }
00054   } catch (bf::filesystem_error /*err*/) {
00055   }
00056 
00057   // assume that "." is always part of the search path, so check locally first
00058 
00059   try {
00060     bf::path local = bf::initial_path() / file;
00061     if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
00062          ( file_type == PR_directory && is_directory( local ) ) ) {
00063       result = bf::complete(file).string();
00064       return true;
00065     }
00066   } catch (bf::filesystem_error /*err*/) {
00067   }
00068 
00069 
00070   // iterate through search list
00071   vector<string> spv;
00072   split(spv, search_list, boost::is_any_of( path_separator), boost::token_compress_on);
00073   for (vector<string>::const_iterator itr = spv.begin();
00074        itr != spv.end(); ++itr ) {
00075 
00076     bf::path fp = *itr / file;
00077 
00078     try {
00079       if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
00080            ( file_type == PR_directory && is_directory( fp ) ) ) {
00081         result = bf::complete(fp).string();
00082         return true;
00083       }
00084     } catch (bf::filesystem_error /*err*/) {
00085     }
00086 
00087 
00088     // if recursive searching requested, drill down
00089     if (search_type == PathResolver::RecursiveSearch &&
00090         is_directory( bf::path(*itr) ) ) {
00091 
00092       bf::recursive_directory_iterator end_itr;
00093       try {
00094         for ( bf::recursive_directory_iterator ritr( *itr );
00095               ritr != end_itr; ++ritr) {
00096 
00097           // skip if not a directory
00098           if (! is_directory( bf::path(*ritr) ) ) { continue; }
00099 
00100           bf::path fp2 = bf::path(*ritr) / file;
00101           if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
00102                ( file_type == PR_directory && is_directory( fp2 ) ) ) {
00103             result = bf::complete( fp2 ).string();
00104             return true;
00105           }
00106         }
00107       } catch (bf::filesystem_error /*err*/) {
00108       }
00109     }
00110 
00111   }
00112 
00113   return found;
00114 }
00115 
00116 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00117 
00118 string
00119 PathResolver::find_file(const std::string& logical_file_name,
00120               const std::string& search_path,
00121               SearchType search_type) {
00122 
00123   const char* path_env = ::getenv (search_path.c_str ());
00124 
00125   std::string path_list;
00126 
00127   if (path_env != 0)
00128   {
00129     path_list = path_env;
00130   }
00131 
00132   return (find_file_from_list (logical_file_name, path_list, search_type));
00133 }
00134 
00135 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00136 
00137 std::string
00138 PathResolver::find_file_from_list (const std::string& logical_file_name,
00139                                    const std::string& search_list,
00140                                    SearchType search_type)
00141 {
00142   std::string result("");
00143 
00144   bf::path lfn( logical_file_name );
00145 
00146   /* bool found = */
00147   PR_find (lfn, search_list, PR_regular_file, search_type, result);
00148 
00149   // The following functionality was in the original PathResolver, but I believe
00150   // that it's WRONG. It extracts the filename of the requested item, and searches
00151   // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
00152   // and that fails, it will look for just "a.txt" in the search list.
00153 
00154   // if (! found && lfn.filename() != lfn ) {
00155   //   result = "";
00156   //   PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
00157   // }
00158 
00159   return (result);
00160 }
00161 
00162 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00163 
00164 string PathResolver::find_directory (const std::string& logical_file_name,
00165                                      const std::string& search_path,
00166                                      SearchType search_type)
00167 {
00168   const char* path_env = ::getenv (search_path.c_str ());
00169 
00170   std::string path_list;
00171 
00172   if (path_env != 0)
00173     {
00174       path_list = path_env;
00175     }
00176 
00177   return (find_directory_from_list (logical_file_name, path_list, search_type));
00178 }
00179 
00180 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00181 
00182 string
00183 PathResolver::find_directory_from_list (const std::string& logical_file_name,
00184                                         const std::string& search_list,
00185                                         SearchType search_type)
00186 {
00187   std::string result;
00188 
00189   if (!PR_find (logical_file_name, search_list, PR_directory, search_type, result))
00190   {
00191     result = "";
00192   }
00193 
00194   return (result);
00195 }
00196 
00197 
00198 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00199 
00200 PathResolver::SearchPathStatus
00201 PathResolver::check_search_path (const std::string& search_path)
00202 {
00203   const char* path_env = ::getenv (search_path.c_str ());
00204 
00205   if (path_env == 0) return (EnvironmentVariableUndefined);
00206 
00207   std::string path_list (path_env);
00208 
00209   vector<string> spv;
00210   boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on);
00211   vector<string>::iterator itr=spv.begin();
00212 
00213   try {
00214     for (; itr!= spv.end(); ++itr) {
00215       bf::path pp(*itr);
00216       if (!is_directory(pp)) {
00217         return (UnknownDirectory);
00218       }
00219     }
00220   } catch(bf::filesystem_error /*err*/) {
00221     return (UnknownDirectory);
00222   }
00223 
00224   return ( Ok );
00225 }
00226 
00227 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00228 
00229 std::string PathResolverFindXMLFile (const std::string& logical_file_name)
00230 {
00231   return PathResolver::find_file (logical_file_name, "XMLPATH");
00232 }
00233 
00234 std::string PathResolverFindDataFile (const std::string& logical_file_name)
00235 {
00236   return PathResolver::find_file (logical_file_name, "DATAPATH");
00237 }
00238 
00239 }  // System namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:24:56 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004