00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <set>
00026 #include <string>
00027 #include <vector>
00028
00029 #include <boost/regex.hpp>
00030
00031 #include "../common/WIOTools.h"
00032 #include "../common/WPathHelper.h"
00033 #include "../common/WSharedLib.h"
00034
00035 #include "WKernel.h"
00036
00037 #include "WModuleLoader.h"
00038
00039 WModuleLoader::WModuleLoader( )
00040 {
00041
00042 }
00043
00044 WModuleLoader::~WModuleLoader()
00045 {
00046
00047 m_libs.clear();
00048 }
00049
00050 void WModuleLoader::load( WSharedAssociativeContainer< std::set< boost::shared_ptr< WModule > > >::WriteTicket ticket,
00051 boost::filesystem::path dir, unsigned int level )
00052 {
00053 for( boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator( dir );
00054 i != boost::filesystem::directory_iterator(); ++i )
00055 {
00056
00057 std::string suffix = getSuffix( i->leaf() );
00058 std::string stem = i->path().stem();
00059
00060 #ifdef _MSC_VER
00061 std::string supposedFilename = getModulePrefix() + '_' + i->path().parent_path().filename()
00062 #ifdef _DEBUG
00063 + 'd'
00064 #endif
00065 + WSharedLib::getSystemSuffix();
00066 std::string isFileName = i->path().filename();
00067 #endif // _MSC_VER
00068
00069
00070 std::string relPath = i->path().file_string();
00071 relPath.erase( 0, dir.file_string().length() + 1 );
00072
00073
00074
00075 #ifdef __WIN32__
00076 static const boost::regex CheckLibMMP( "^.*\\" + WSharedLib::getSystemSuffix() +"$" );
00077 #elif __APPLE__
00078 static const boost::regex CheckLibMMP( "^.*\\.[0-9]+\\.[0-9]+\\.[0-9]+\\" + WSharedLib::getSystemSuffix() + "$" );
00079 #else
00080 static const boost::regex CheckLibMMP( "^.*\\" + WSharedLib::getSystemSuffix() + "\\.[0-9]+\\.[0-9]+\\.[0-9]+$" );
00081 #endif
00082 boost::smatch matches;
00083
00084 if( !boost::filesystem::is_directory( *i ) &&
00085 ( boost::regex_match( i->path().string(), matches, CheckLibMMP ) ) &&
00086 ( stem.compare( 0, getModulePrefix().length(), getModulePrefix() ) == 0 )
00087 #ifdef _MSC_VER
00088 && supposedFilename == isFileName
00089 #endif
00090 )
00091 {
00092 try
00093 {
00094
00095 boost::shared_ptr< WSharedLib > l = boost::shared_ptr< WSharedLib >( new WSharedLib( i->path() ) );
00096
00097
00098 W_LOADABLE_MODULE_SIGNATURE f;
00099 l->fetchFunction< W_LOADABLE_MODULE_SIGNATURE >( W_LOADABLE_MODULE_SYMBOL, f );
00100
00101
00102 WModuleList m;
00103 f( m );
00104
00105
00106 if( m.empty() )
00107 {
00108 WLogger::getLogger()->addLogMessage( "Load failed for module \"" + relPath + "\". Could not create any " +
00109 "prototype instance.", "Module Loader", LL_ERROR );
00110 continue;
00111 }
00112 else
00113 {
00114
00115 for( WModuleList::const_iterator iter = m.begin(); iter != m.end(); ++iter )
00116 {
00117 ( *iter )->setLocalPath( i->path().parent_path() );
00118 ticket->get().insert( *iter );
00119 m_libs.push_back( l );
00120 }
00121
00122 wlog::debug( "Module Loader" ) << "Loaded " << m.size() << " modules from " << relPath;
00123 }
00124
00125
00126 }
00127 catch( const WException& e )
00128 {
00129 WLogger::getLogger()->addLogMessage( "Load failed for module \"" + relPath + "\". " + e.what() + ". Ignoring.",
00130 "Module Loader", LL_ERROR );
00131 }
00132 }
00133 else if( ( level == 0 ) && boost::filesystem::is_directory( *i ) )
00134 {
00135
00136 load( ticket, *i, level + 1 );
00137 }
00138 }
00139 }
00140
00141 void WModuleLoader::load( WSharedAssociativeContainer< std::set< boost::shared_ptr< WModule > > >::WriteTicket ticket )
00142 {
00143 std::vector< boost::filesystem::path > allPaths = WPathHelper::getAllModulePaths();
00144
00145
00146 for( std::vector< boost::filesystem::path >::const_iterator path = allPaths.begin(); path != allPaths.end(); ++path )
00147 {
00148 WLogger::getLogger()->addLogMessage( "Searching modules in \"" + ( *path ).file_string() + "\".", "Module Loader", LL_INFO );
00149
00150
00151 if( !boost::filesystem::is_directory( *path ) || !boost::filesystem::exists( *path ) )
00152 {
00153 WLogger::getLogger()->addLogMessage( "Searching modules in \"" + ( *path ).file_string() +
00154 "\" failed. It is not a directory or does not exist." +
00155 " Ignoring.", "Module Loader", LL_WARNING );
00156
00157 continue;
00158 }
00159
00160
00161 load( ticket, *path );
00162 }
00163 }
00164
00165 std::string WModuleLoader::getModulePrefix()
00166 {
00167
00168 return WSharedLib::getSystemPrefix();
00169 }
00170