X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface%2FPlugins.cxx;h=1543d314a25443d1ce8e7068b01bc990ea6d2099;hb=ff82c0202d0496bb65bc4cb07e63604616db2961;hp=260172e467c41e1b0d93ca5a1d0d6d419189aaa7;hpb=1f5c3516bf4240bcdd91979ac303298ef1f75fc3;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface/Plugins.cxx b/lib/cpPlugins/Interface/Plugins.cxx index 260172e..1543d31 100644 --- a/lib/cpPlugins/Interface/Plugins.cxx +++ b/lib/cpPlugins/Interface/Plugins.cxx @@ -1,18 +1,20 @@ #include #include -#include -#include -#include +#include +#include + +// ------------------------------------------------------------------------- +cpPlugins::Interface::Plugins::Pointer +cpPlugins::Interface::Plugins::m_Singleton = NULL; // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: New( ) { - static Pointer singleton = NULL; - if( singleton.IsNull( ) ) - singleton = new Self( ); - return( singleton ); + if( Self::m_Singleton.IsNull( ) ) + Self::m_Singleton = new Self( ); + return( Self::m_Singleton ); } // ------------------------------------------------------------------------- @@ -20,7 +22,7 @@ itk::LightObject::Pointer cpPlugins::Interface::Plugins:: CreateAnother( ) const { itk::LightObject::Pointer smartPtr; - smartPtr = NULL; + smartPtr = Self::m_Singleton; return( smartPtr ); } @@ -29,413 +31,201 @@ cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: Clone( ) const { - Pointer r = NULL; - return( r ); + return( Self::m_Singleton ); } // ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -TStrings cpPlugins::Interface::Plugins:: -GetLibraries( ) const +const cpPlugins::Interface::Plugins:: +TFilters& cpPlugins::Interface::Plugins:: +GetFilters( ) const { - TStrings res; - for( - auto i = this->m_Libraries.begin( ); i != this->m_Libraries.end( ); ++i - ) - res.insert( i->first ); - return( res ); + return( this->m_Filters ); } // ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -TStrings cpPlugins::Interface::Plugins:: -GetPlugins( ) const +void cpPlugins::Interface::Plugins:: +LoadPluginsFile( const std::string& libname ) { - TStrings res; - for( auto i = this->m_Plugins.begin( ); i != this->m_Plugins.end( ); ++i ) - res.insert( i->first ); - return( res ); + std::map< std::string, std::set< std::string > > filters; + cpPlugins::OS::DLLManager::GetPluginsLibraryContents( filters, libname ); + THandlers zero( NULL, NULL ); + for( auto i : filters ) + for( auto j : i.second ) + this->m_Filters[ i.first ][ j ] = TLibData( libname, zero ); } // ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -TStrings cpPlugins::Interface::Plugins:: -GetCategories( ) const +void cpPlugins::Interface::Plugins:: +LoadPluginsDirectory( const std::string& dir ) { - TStrings res; - for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) - res.insert( i->first ); - return( res ); -} + // Create a globbing pattern + std::stringstream glob; + glob << cpPlugins_LIB_PREFIX << "*" << cpPlugins_LIB_EXT; -// ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -TStrings cpPlugins::Interface::Plugins:: -GetFilters( const std::string& category ) const -{ - TStrings res; - auto cIt = this->m_Filters.find( category ); - if( cIt != this->m_Filters.end( ) ) - for( auto i = cIt->second.begin( ); i != cIt->second.end( ); ++i ) - res.insert( i->first ); - return( res ); + // Get possible shared libraries + std::set< std::string > files = + cpPlugins::OS::LoadDirContents( dir, false, glob.str( ) ); + this->m_PluginsPaths.insert( dir ); + for( auto f : files ) + try { this->LoadPluginsFile( f ); } catch( ... ) { } } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: -AddEnvironments( const std::string& env ) +GuessPlugins( ) { - std::vector< std::string > directories; - cpExtensions::Tokenize( directories, env, cpPlugins_ENV_SEPARATOR ); - for( auto dir = directories.begin( ); dir != directories.end( ); ++dir ) - this->m_Paths.insert( cpExtensions::CanonicalPath( *dir ) ); -} + // Create a globbing pattern + std::stringstream glob; + glob << cpPlugins_LIB_PREFIX << "*" << cpPlugins_LIB_EXT; -// ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -LoadEnvironments( ) -{ - std::set< std::string > libs; - for( auto d = this->m_Paths.begin( ); d != this->m_Paths.end( ); ++d ) + // Update paths and get possible shared libraries + this->_ReadPluginsPathsVariable( ); + for( auto dir : this->m_PluginsPaths ) { - std::stringstream fname; - fname << *d << cpPlugins_PATH_SEPARATOR << cpPlugins_CONFIG; - std::string buffer; - if( cpExtensions::Read( buffer, fname.str( ) ) ) - { - std::istringstream input( buffer ); - for( std::string line; std::getline( input, line ); ) - { - std::vector< std::string > tokens; - cpExtensions::Tokenize( tokens, line, "|" ); - if( tokens.size( ) == 2 ) - { - std::string pth = tokens[ 0 ]; - std::string lib = tokens[ 1 ]; - if( lib.find( "*" ) != std::string::npos ) - { - std::string ext( cpPlugins_LIB_EXT ); - DIR* dir; - struct dirent* ent; - if( ( dir = opendir( pth.c_str( ) ) ) != NULL ) - { - while( ( ent = readdir( dir ) ) != NULL ) - { - std::string fname( ent->d_name ); - long pos = long( fname.size( ) ) - long( ext.size( ) ); - if( pos > 0 ) - { - if( fname.substr( pos ) == ext ) - { - std::regex re( lib ); -std::smatch match; -if( std::regex_search( fname, match, re ) && match.size( ) >= 1 ) - { - std::stringstream str; - str - << pth << cpPlugins_PATH_SEPARATOR << fname; - libs.insert( str.str( ) ); - } // fi - - } // fi - - } // fi - - } // elihw - closedir( dir ); - - } // fi - } - else - { - std::stringstream str; - str - << pth << cpPlugins_PATH_SEPARATOR << cpPlugins_LIB_PREFIX - << lib << cpPlugins_LIB_EXT; - libs.insert( str.str( ) ); - - } // fi - - } // fi - - } // rof - - } // fi - - } // rof - for( auto l = libs.begin( ); l != libs.end( ); ++l ) - { - std::string lib = cpExtensions::CanonicalPath( *l ); - if( lib != "" ) - { - if( this->m_Libraries.find( lib ) == this->m_Libraries.end( ) ) -{ - std::string error = ""; - void* hnd = cpPlugins::OS::DLLManager::Load( lib, error ); - if( hnd != NULL ) - this->m_Libraries[ lib ] = hnd; - -} // fi - - } // fi + std::set< std::string > files = + cpPlugins::OS::LoadDirContents( dir, false, glob.str( ) ); + for( auto f : files ) + try { this->LoadPluginsFile( f ); } catch( ... ) { } } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: -LoadPaths( const std::string& dir ) +GuessEnvironment( const std::string& dir ) { - std::stringstream fname, envs; - fname << dir; - if( !cpExtensions::IsPathSeparator( dir.back( ) ) ) - fname << cpExtensions_PATH_SEPARATOR; - fname << cpPlugins_PATHS; - std::string buffer; - if( cpExtensions::Read( buffer, fname.str( ) ) ) - { - std::istringstream input( buffer ); - for( std::string line; std::getline( input, line ); ) - envs << line << cpPlugins_ENV_SEPARATOR; + std::stringstream fname; + fname << dir << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS; + std::string buffer; + if( cpPlugins::Read( buffer, fname.str( ) ) ) + { + std::istringstream input( buffer ); + for( std::string line; std::getline( input, line ); ) + this->m_PluginsPaths.insert( cpPlugins::CanonicalPath( line ) ); - } // fi - if( envs.str( ).size( ) > 0 ) - this->AddEnvironments( envs.str( ) ); + } // fi } // ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -SavePaths( const std::string& dir ) const +bool cpPlugins::Interface::Plugins:: +SaveEnvironment( const std::string& dir ) { std::stringstream buffer; - for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) - buffer << *i << std::endl; - + for( auto p : this->m_PluginsPaths ) + buffer << p << std::endl; std::stringstream fname; - fname << dir; - if( !cpExtensions::IsPathSeparator( dir.back( ) ) ) - fname << cpExtensions_PATH_SEPARATOR; - fname << cpPlugins_PATHS; - if( !cpExtensions::Write( buffer.str( ), fname.str( ) ) ) - throw std::runtime_error( "Error writing environment file." ); + fname << dir << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS; + return( cpPlugins::Write( buffer.str( ), fname.str( ) ) ); } // ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -LoadFile( const std::string& fname ) -{ - // Resolve canonical filename - std::string can_name = cpExtensions::CanonicalPath( fname ); - if( can_name == "" ) - throw std::runtime_error( - std::string( "Loading file: can't find library \"" ) + - fname + - std::string( "\"" ) - ); - if( this->m_Plugins.find( can_name ) != this->m_Plugins.end( ) ) - return; - - // Load the library - std::string error = ""; - void* hnd = cpPlugins::OS::DLLManager::Load( can_name, error ); - if( hnd == NULL ) - throw std::runtime_error( - std::string( "Loading plugin library: " ) + error - ); - - // Get plugins name - typedef const char* ( *_TFunction )( ); - _TFunction plugins_name_function = ( _TFunction )( - cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_Name" ) - ); - if( plugins_name_function == NULL ) - { - cpPlugins::OS::DLLManager::UnLoad( hnd ); - throw std::runtime_error( - std::string( "Library \"" ) + - can_name + - std::string( "\" not recognized as a cpPlugins library" ) - ); - - } // fi - std::string plugins_name = plugins_name_function( ); - - // Get loaded filters - _TFunction function = ( _TFunction )( - cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_LoadedFilters" ) - ); - if( function == NULL ) - { - cpPlugins::OS::DLLManager::UnLoad( hnd ); - throw std::runtime_error( - std::string( "Library \"" ) + - can_name + - std::string( "\" not recognized as a cpPlugins library" ) - ); - - } // fi - std::string descriptors = function( ); - std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' ); - std::istringstream str( descriptors ); - TFilters filters; - while( str ) +cpPlugins::BaseObjects::ProcessObject::Pointer +cpPlugins::Interface::Plugins:: +CreateFilter( const std::string& category, const std::string& name ) +{ + std::cout << "1" << std::endl; + typedef void* ( *_TCreator )( ); + std::cout << "2" << std::endl; + typedef cpPlugins::BaseObjects::ProcessObject::Pointer _TPtr; + std::cout << "3" << std::endl; + _TPtr o = NULL; + std::cout << "4" << std::endl; + auto cat = this->m_Filters.find( category ); + std::cout << "5" << std::endl; + if( cat != this->m_Filters.end( ) ) { - std::string value, category, name; - str >> value; - if( value == "" ) - continue; - std::replace( value.begin( ), value.end( ), ':', ' ' ); - std::istringstream value_str( value ); - value_str >> category >> name; - - // Check if the filter has been already loaded - bool found = false; - auto fIt = this->m_Filters.find( category ); - if( fIt != this->m_Filters.end( ) ) - found = fIt->second.find( name ) != fIt->second.end( ); - if( found ) + std::cout << "6" << std::endl; + auto nam = cat->second.find( name ); + std::cout << "7" << std::endl; + if( nam != cat->second.end( ) ) { - cpPlugins::OS::DLLManager::UnLoad( hnd ); - throw std::runtime_error( - std::string( "Filter \"" ) + - category + std::string( "::" ) + name + - std::string( "\" already exists." ) - ); + std::cout << "8" << std::endl; + void* l_hnd = nam->second.second.first; + std::cout << "9" << std::endl; + void* f_hnd = nam->second.second.second; + std::cout << "10" << std::endl; + if( l_hnd == NULL ) + { + std::cout << "11" << std::endl; + l_hnd = cpPlugins::OS::DLLManager::LoadPlugins( nam->second.first ); + std::cout << "12" << std::endl; + nam->second.second.first = l_hnd; + std::cout << "13" << std::endl; + + } // fi + if( f_hnd == NULL ) + { + std::cout << "14" << std::endl; + f_hnd = + cpPlugins::OS::DLLManager::LoadCreator( l_hnd, category, name ); + std::cout << "15" << std::endl; + nam->second.second.second = f_hnd; + std::cout << "16" << std::endl; + + } // fi + std::cout << "17" << std::endl; + _TCreator creator = reinterpret_cast< _TCreator >( f_hnd ); + std::cout << "18" << std::endl; + if( creator != NULL ) + { + std::cout << "19 " << creator << " " << f_hnd << std::endl; + void* a = creator( ); + std::cout << "20" << std::endl; + std::cout << "20 " << creator << " " << a << std::endl; + std::cout << "21" << std::endl; + o = reinterpret_cast< _TPtr* >( a )->GetPointer( ); + std::cout << "22" << std::endl; + o->SetName( name ); + std::cout << "23" << std::endl; + o->SetPluginName( nam->second.first ); + std::cout << "24" << std::endl; + + } // fi } // fi - // Get filter creator - TCreator creator = ( TCreator )( - cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, category + "_" + name ) + } // fi + std::cout << "25" << std::endl; + if( o.IsNull( ) ) + throw std::runtime_error( + std::string( "Could not create a valid ProcessObject of type \"" ) + + category + std::string( ":" ) + + name + std::string( "\"" ) ); - if( creator == NULL ) - { - cpPlugins::OS::DLLManager::UnLoad( hnd ); - throw std::runtime_error( - std::string( "Filter \"" ) + - category + std::string( "::" ) + name + - std::string( "\" does not have a valid creator." ) - ); - - } // fi - - TCreatorData data; - data.PluginName = plugins_name; - data.LibraryHandle = hnd; - data.Creator = creator; - filters[ category ][ name ] = data; - - } // elihw - - // Keep track of all loaded handlers - for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt ) - for( auto nIt = cIt->second.begin( ); nIt != cIt->second.end( ); ++nIt ) - this->m_Filters[ cIt->first ][ nIt->first ] = nIt->second; - this->m_Plugins[ can_name ] = hnd; + std::cout << "26" << std::endl; + return( o ); } // ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -LoadPlugin( const std::string& pname ) +cpPlugins::Interface::Plugins:: +Plugins( ) + : Superclass( ) { - std::stringstream fname; - fname << cpPlugins_LIB_PREFIX << pname << cpPlugins_LIB_EXT; - unsigned int count = 0; - for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) - { - std::stringstream dir; - dir << *i; - if( !cpExtensions::IsPathSeparator( i->back( ) ) ) - dir << cpExtensions_PATH_SEPARATOR; - dir << fname.str( ); - try - { - this->LoadFile( dir.str( ) ); - } - catch( ... ) - { - count++; - - } // yrt - - } // rof - - // Throw error, if any - if( count == this->m_Paths.size( ) ) - throw std::runtime_error( - std::string( "Could not load plugin " ) + - std::string( "\"" ) + pname + - std::string( "\" from any registered path." ) - ); + cpPlugins::OS::DLLManager::TeaseLoadedLibraries( ); } // ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -LoadDirectory( const std::string& dirname ) +cpPlugins::Interface::Plugins:: +~Plugins( ) { - DIR* dir; - struct dirent* ent; - if( ( dir = opendir( dirname.c_str( ) ) ) != NULL ) - { - while( ( ent = readdir( dir ) ) != NULL ) - { - try - { - std::stringstream fname; - fname << dirname << cpExtensions_PATH_SEPARATOR << ent->d_name; - this->LoadFile( fname.str( ) ); - } - catch( ... ) { } - - } // elihw - closedir( dir ); - } - else - throw std::runtime_error( - std::string( "Could not load directory " ) + - std::string( "\"" ) + dirname + std::string( "\"" ) - ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: -GuessPlugins( ) +PrintSelf( std::ostream& os, itk::Indent indent ) const { - for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) + for( auto i : this->m_Filters ) { - try { this->LoadDirectory( *i ); } - catch( ... ) { } + os << indent << "+ " << i.first << std::endl; + for( auto j : i.second ) + os << indent << "|----> " << j.first << std::endl; } // rof } // ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins::TProcess::Pointer -cpPlugins::Interface::Plugins:: -CreateProcessObject( const std::string& category, const std::string& name ) -{ - typedef cpPlugins::BaseObjects::ProcessObject::Pointer _Ptr; - _Ptr o = NULL; - auto cIt = this->m_Filters.find( category ); - if( cIt != this->m_Filters.end( ) ) - { - auto nIt = cIt->second.find( name ); - if( nIt != cIt->second.end( ) ) - { - o = reinterpret_cast< _Ptr* >( nIt->second.Creator( ) )->GetPointer( ); - o->SetName( name ); - o->SetPluginName( nIt->second.PluginName ); - - } // fi - - } // fi - return( o ); -} - -// ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -Plugins( ) - : Superclass( ) +void cpPlugins::Interface::Plugins:: +_ReadPluginsPathsVariable( ) { #ifdef cpPlugins_OS_Windows char* p; @@ -448,39 +238,10 @@ Plugins( ) if( p != NULL ) str << p << cpPlugins_ENV_SEPARATOR; str << "."; - this->AddEnvironments( str.str( ) ); -} - -// ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -~Plugins( ) -{ -} - -// ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -PrintSelf( std::ostream& os, itk::Indent indent ) const -{ - // Show data - os << indent << "----- PATHS -----" << std::endl; - auto paths = this->GetPaths( ); - for( auto paIt = paths.begin( ); paIt != paths.end( ); ++paIt ) - os << indent << *paIt << std::endl; - os << indent << std::endl << indent << "----- PLUGINS -----" << std::endl; - auto plugins = this->GetPlugins( ); - for( auto plIt = plugins.begin( ); plIt != plugins.end( ); ++plIt ) - os << indent << *plIt << std::endl; - os << indent << std::endl << indent << "----- FILTERS -----" << std::endl; - auto categories = this->GetCategories( ); - for( auto cIt = categories.begin( ); cIt != categories.end( ); ++cIt ) - { - os << indent << "** Category: " << *cIt << " **" << std::endl; - auto filters = this->GetFilters( *cIt ); - for( auto fIt = filters.begin( ); fIt != filters.end( ); ++fIt ) - os << indent << indent << indent << "Filter: " << *fIt << std::endl; - - } // rof - + std::vector< std::string > tokens; + cpPlugins::Tokenize( tokens, str.str( ), cpPlugins_ENV_SEPARATOR ); + for( auto dir : tokens ) + this->m_PluginsPaths.insert( cpPlugins::CanonicalPath( dir ) ); } // eof - $RCSfile$