Gaudi Framework, version v21r11

Home   Generated: 30 Sep 2010

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   // assume that "." is always part of the search path, so check locally first
00047 
00048   try {
00049     bf::path local = bf::initial_path() / file;
00050     if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
00051          ( file_type == PR_directory && is_directory( local ) ) ) {
00052       result = bf::complete(file).string();
00053       return true;
00054     }
00055   } catch (bf::filesystem_error /*err*/) {
00056   }
00057 
00058 
00059   // iterate through search list
00060   vector<string> spv;
00061   split(spv, search_list, boost::is_any_of( path_separator), boost::token_compress_on);
00062   for (vector<string>::const_iterator itr = spv.begin();
00063        itr != spv.end(); ++itr ) {
00064 
00065     bf::path fp = *itr / file;
00066 
00067     try {
00068       if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
00069            ( file_type == PR_directory && is_directory( fp ) ) ) {
00070         result = bf::complete(fp).string();
00071         return true;
00072       }
00073     } catch (bf::filesystem_error /*err*/) {
00074     }
00075 
00076 
00077     // if recursive searching requested, drill down
00078     if (search_type == PathResolver::RecursiveSearch &&
00079         is_directory( bf::path(*itr) ) ) {
00080 
00081       bf::recursive_directory_iterator end_itr;
00082       try {
00083         for ( bf::recursive_directory_iterator ritr( *itr );
00084               ritr != end_itr; ++ritr) {
00085 
00086           // skip if not a directory
00087           if (! is_directory( bf::path(*ritr) ) ) { continue; }
00088 
00089           bf::path fp2 = bf::path(*ritr) / file;
00090           if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
00091                ( file_type == PR_directory && is_directory( fp2 ) ) ) {
00092             result = bf::complete( fp2 ).string();
00093             return true;
00094           }
00095         }
00096       } catch (bf::filesystem_error /*err*/) {
00097       }
00098     }
00099 
00100   }
00101 
00102   return found;
00103 }
00104 
00105 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00106 
00107 string
00108 PathResolver::find_file(const std::string& logical_file_name,
00109               const std::string& search_path,
00110               SearchType search_type) {
00111 
00112   const char* path_env = ::getenv (search_path.c_str ());
00113 
00114   std::string path_list;
00115 
00116   if (path_env != 0)
00117   {
00118     path_list = path_env;
00119   }
00120 
00121   return (find_file_from_list (logical_file_name, path_list, search_type));
00122 }
00123 
00124 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00125 
00126 std::string
00127 PathResolver::find_file_from_list (const std::string& logical_file_name,
00128                                    const std::string& search_list,
00129                                    SearchType search_type)
00130 {
00131   std::string result("");
00132 
00133   bf::path lfn( logical_file_name );
00134 
00135   /* bool found = */
00136   PR_find (lfn, search_list, PR_regular_file, search_type, result);
00137 
00138   // The following functionality was in the original PathResolver, but I believe
00139   // that it's WRONG. It extracts the filename of the requested item, and searches
00140   // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
00141   // and that fails, it will look for just "a.txt" in the search list.
00142 
00143   // if (! found && lfn.filename() != lfn ) {
00144   //   result = "";
00145   //   PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
00146   // }
00147 
00148   return (result);
00149 }
00150 
00151 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00152 
00153 string PathResolver::find_directory (const std::string& logical_file_name,
00154                                      const std::string& search_path,
00155                                      SearchType search_type)
00156 {
00157   const char* path_env = ::getenv (search_path.c_str ());
00158 
00159   std::string path_list;
00160 
00161   if (path_env != 0)
00162     {
00163       path_list = path_env;
00164     }
00165 
00166   return (find_directory_from_list (logical_file_name, path_list, search_type));
00167 }
00168 
00169 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00170 
00171 string
00172 PathResolver::find_directory_from_list (const std::string& logical_file_name,
00173                                         const std::string& search_list,
00174                                         SearchType search_type)
00175 {
00176   std::string result;
00177 
00178   if (!PR_find (logical_file_name, search_list, PR_directory, search_type, result))
00179   {
00180     result = "";
00181   }
00182 
00183   return (result);
00184 }
00185 
00186 
00187 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00188 
00189 PathResolver::SearchPathStatus
00190 PathResolver::check_search_path (const std::string& search_path)
00191 {
00192   const char* path_env = ::getenv (search_path.c_str ());
00193 
00194   if (path_env == 0) return (EnvironmentVariableUndefined);
00195 
00196   std::string path_list (path_env);
00197 
00198   vector<string> spv;
00199   boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on);
00200   vector<string>::iterator itr=spv.begin();
00201 
00202   try {
00203     for (; itr!= spv.end(); ++itr) {
00204       bf::path pp(*itr);
00205       if (!is_directory(pp)) {
00206         return (UnknownDirectory);
00207       }
00208     }
00209   } catch(bf::filesystem_error /*err*/) {
00210     return (UnknownDirectory);
00211   }
00212 
00213   return ( Ok );
00214 }
00215 
00216 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00217 
00218 std::string PathResolverFindXMLFile (const std::string& logical_file_name)
00219 {
00220   return PathResolver::find_file (logical_file_name, "XMLPATH");
00221 }
00222 
00223 std::string PathResolverFindDataFile (const std::string& logical_file_name)
00224 {
00225   return PathResolver::find_file (logical_file_name, "DATAPATH");
00226 }
00227 
00228 }  // System namespace

Generated at Thu Sep 30 09:57:35 2010 for Gaudi Framework, version v21r11 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004