#include #include #include #include // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: New( ) { static Pointer singleton = NULL; if( singleton.IsNull( ) ) singleton = new Self( ); return( singleton ); } // ------------------------------------------------------------------------- itk::LightObject::Pointer cpPlugins::Interface::Plugins:: CreateAnother( ) const { itk::LightObject::Pointer smartPtr; smartPtr = NULL; return( smartPtr ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: Clone( ) const { Pointer r = NULL; return( r ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetLibraries( ) const { TStrings res; for( auto i = this->m_Libraries.begin( ); i != this->m_Libraries.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetPlugins( ) const { TStrings res; for( auto i = this->m_Plugins.begin( ); i != this->m_Plugins.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetCategories( ) const { TStrings res; for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- 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 ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: AddEnvironments( const std::string& new_environment ) { std::vector< std::string > tokens; cpExtensions::Tokenize( tokens, new_environment, cpPlugins_ENV_SEPARATOR ); for( auto i = tokens.begin( ); i != tokens.end( ); ++i ) { std::stringstream dir; dir << cpExtensions::CanonicalPath( *i ); if( dir.str( ) != "" ) { if( !cpExtensions::IsPathSeparator( dir.str( ).back( ) ) ) dir << cpExtensions_PATH_SEPARATOR; std::stringstream name; name << dir.str( ) << cpPlugins_CONFIG; std::ifstream check( name.str( ).c_str( ), std::ifstream::binary ); if( check ) this->m_Paths.insert( dir.str( ) ); check.close( ); } // fi } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadEnvironments( ) { std::stringstream all_errors; for( auto d = this->m_Paths.begin( ); d != this->m_Paths.end( ); ++d ) { std::stringstream name; name << *d << cpPlugins_CONFIG; std::string buffer; if( cpExtensions::Read( buffer, name.str( ) ) ) { std::istringstream input( buffer ); for( std::string line; std::getline( input, line ); ) { std::vector< std::string > tokens; cpExtensions::Tokenize( tokens, line, "@" ); std::string library_file = ""; if( tokens[ 0 ] == "local" ) library_file = cpExtensions::CanonicalPath( *d + std::string( cpPlugins_LIB_PREFIX ) + tokens[ 1 ] + std::string( cpPlugins_LIB_EXT ) ); else if( tokens[ 0 ] == "global" ) library_file = tokens[ 1 ]; if( library_file != "" ) { std::string error = ""; void* hnd = cpPlugins::OS::DLLManager::Load( library_file, error ); if( hnd != NULL ) this->m_Libraries[ library_file ] = hnd; else all_errors << " ; " << error; } // fi } // rof } // fi } // rof // Throw errors if( all_errors.str( ) != "" ) throw std::runtime_error( std::string( "Loading environment libraries errors: " ) + all_errors.str( ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: SaveEnvironments( const std::string& dir ) const { if( this->m_Paths.size( ) > 0 ) { std::stringstream buffer; auto i = this->m_Paths.begin( ); for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) buffer << *i << 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." ); } else throw std::runtime_error( "No paths to save." ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: OpenEnvironments( const std::string& dir ) { std::stringstream fname; 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 ); std::stringstream paths; for( std::string line; std::getline( input, line ); ) paths << line << cpPlugins_ENV_SEPARATOR; this->AddEnvironments( paths.str( ) ); } else throw std::runtime_error( "Error opening environment file." ); } // ------------------------------------------------------------------------- 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 ) { 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 ) { cpPlugins::OS::DLLManager::UnLoad( hnd ); throw std::runtime_error( std::string( "Filter \"" ) + category + std::string( "::" ) + name + std::string( "\" already exists." ) ); } // fi // Get filter creator TCreator creator = ( TCreator )( cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, category + "_" + name ) ); 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; } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadPlugin( const std::string& pname ) { 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." ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadDirectory( const std::string& dirname ) { 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( ) { for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) { try { this->LoadDirectory( *i ); } catch( ... ) { } } // 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( ) { char* p = std::getenv( cpPlugins_PATHS ); std::stringstream str; 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 } // eof - $RCSfile$