// ========================================================================= // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ========================================================================= #include #include #include #include #include // ------------------------------------------------------------------------- namespace cpPlugins { bool Manager::m_Configured = false; Manager::TLibraries Manager::m_Libraries; Manager::TPlugins Manager::m_Plugins; } // end namespace // ------------------------------------------------------------------------- cpPlugins::Manager:: Manager( ) { } // ------------------------------------------------------------------------- cpPlugins::Manager:: ~Manager( ) { } // ------------------------------------------------------------------------- void cpPlugins::Manager:: Print( std::ostream& out ) const { out << "----------------------------------------------" << std::endl << " *** cpPlugins::Interface::Manager ***" << std::endl << " * Reachable plugins:" << std::endl << std::endl; for( const TLibraries::value_type& l: this->m_Libraries ) { out << " + " << l.first << std::endl; out << " --> Library:" << l.second.GetPath( ) << std::endl; out << " --> Loadable objects:" << std::endl; for( const std::string& o: l.second.GetContents( ) ) out << " > " << o << std::endl; out << std::endl; } // end for out << "----------------------------------------------"; } // ------------------------------------------------------------------------- const cpPlugins::Manager:: TPlugins& cpPlugins::Manager:: GetPlugins( ) const { return( Self::m_Plugins ); } // ------------------------------------------------------------------------- void cpPlugins::Manager:: Configure( ) { static const std::string paths[] = { cpPlugins_ENV, "LD_LIBRARY_PATH", "PATH", "Path", "DYLD_LIBRARY_PATH" }; static const unsigned int paths_count = 4; if( !Self::m_Configured ) { this->AddPath( "." ); for( unsigned int i = 0; i < paths_count; ++i ) { const char* env_p = std::getenv( paths[ i ].c_str( ) ); if( env_p != NULL ) { std::string str = env_p; typedef boost::char_separator< char > _TSep; typedef boost::tokenizer< _TSep > _TTok; _TSep sep{ cpPlugins_ENV_SEP }; _TTok tokens{ str, sep }; for( const std::string& t: tokens ) this->AddPath( t ); } // end if } // end for Self::m_Configured = true; } // end if } // ------------------------------------------------------------------------- void cpPlugins::Manager:: AddPath( const std::string& p ) { namespace bf = boost::filesystem; try { bf::path cp = bf::canonical( bf::path( p ) ); if( bf::is_directory( cp ) ) { bf::directory_iterator dIt( cp ); for( ; dIt != bf::directory_iterator( ); ++dIt ) { if( dIt->path( ).extension( ).string( ) == cpPlugins_EXT ) this->AddFile( dIt->path( ).string( ) ); } // end for } else { if( cp.extension( ).string( ) == cpPlugins_EXT ) this->AddFile( cp.string( ) ); } // end if } catch( ... ) { } } // ------------------------------------------------------------------------- void cpPlugins::Manager:: AddFile( const std::string& f ) { typedef TLibraries::value_type _TLib; typedef TPlugins::value_type _TPlg; namespace bf = boost::filesystem; try { bf::path cf = bf::canonical( bf::path( f ) ); if( bf::is_directory( cf ) ) { bf::directory_iterator dIt( cf ); for( ; dIt != bf::directory_iterator( ); ++dIt ) { if( dIt->path( ).extension( ).string( ) == cpPlugins_EXT ) this->AddFile( dIt->path( ).string( ) ); } // end for } else { if( cf.extension( ).string( ) == cpPlugins_EXT ) { std::string n = cf.filename( ).string( ); if( Self::m_Libraries.find( n ) == Self::m_Libraries.end( ) ) { TLibraries::iterator lIt = Self::m_Libraries.insert( _TLib( n, cpPlugins::Library( cf.string( ) ) ) ).first; for( const std::string& f: lIt->second.GetContents( ) ) Self::m_Plugins.insert( _TPlg( f, n ) ); } // end if } // end if } // end if } catch( ... ) { } } // ------------------------------------------------------------------------- std::shared_ptr< cpPlugins::ProcessObject > cpPlugins::Manager:: Create( const std::string& name ) { TPlugins::iterator pIt = Self::m_Plugins.find( name ); if( pIt != Self::m_Plugins.end( ) ) { TLibraries::iterator lIt = Self::m_Libraries.find( pIt->second ); if( lIt != Self::m_Libraries.end( ) ) return( lIt->second.Create( name ) ); } // end if cpPluginsErrorMacro( this, << "Could not create an object of type \"" << name << "\"." ); } // eof - $RCSfile$