]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Interface/Plugins.cxx
9da2f70e9d31b54fa3233a41eff6fcb9af64250d
[cpPlugins.git] / lib / cpPlugins / Interface / Plugins.cxx
1 #include <cpPlugins/Interface/Plugins.h>
2 #include <cpPlugins/OS/DLLManager.h>
3 #include <cpPlugins/OS/DirContents.h>
4 #include <cpPlugins/Utility.h>
5
6 // -------------------------------------------------------------------------
7 cpPlugins::Interface::Plugins::Pointer
8 cpPlugins::Interface::Plugins::m_Singleton = NULL;
9
10 // -------------------------------------------------------------------------
11 cpPlugins::Interface::Plugins::
12 Pointer cpPlugins::Interface::Plugins::
13 New( )
14 {
15   if( Self::m_Singleton.IsNull( ) )
16     Self::m_Singleton = new Self( );
17   return( Self::m_Singleton );
18 }
19
20 // -------------------------------------------------------------------------
21 itk::LightObject::Pointer cpPlugins::Interface::Plugins::
22 CreateAnother( ) const
23 {
24   itk::LightObject::Pointer smartPtr;
25   smartPtr = Self::m_Singleton;
26   return( smartPtr );
27 }
28
29 // -------------------------------------------------------------------------
30 cpPlugins::Interface::Plugins::
31 Pointer cpPlugins::Interface::Plugins::
32 Clone( ) const
33 {
34   return( Self::m_Singleton );
35 }
36
37 // -------------------------------------------------------------------------
38 const cpPlugins::Interface::Plugins::
39 TFilters& cpPlugins::Interface::Plugins::
40 GetFilters( ) const
41 {
42   return( this->m_Filters );
43 }
44
45 // -------------------------------------------------------------------------
46 void cpPlugins::Interface::Plugins::
47 LoadPluginsFile( const std::string& libname )
48 {
49   std::map< std::string, std::set< std::string > > filters;
50   cpPlugins::OS::DLLManager::GetPluginsLibraryContents( filters, libname );
51   THandlers zero( NULL, NULL );
52   for( auto i : filters )
53     for( auto j : i.second )
54       this->m_Filters[ i.first ][ j ] = TLibData( libname, zero );
55 }
56
57 // -------------------------------------------------------------------------
58 void cpPlugins::Interface::Plugins::
59 LoadPluginsDirectory( const std::string& dir )
60 {
61   // Create a globbing pattern
62   std::stringstream glob;
63   glob << cpPlugins_LIB_PREFIX << "*" << cpPlugins_LIB_EXT;
64
65   // Get possible shared libraries
66   std::set< std::string > files =
67     cpPlugins::OS::LoadDirContents( dir, false, glob.str( ) );
68   this->m_PluginsPaths.insert( dir );
69   for( auto f : files )
70     try { this->LoadPluginsFile( f ); } catch( ... ) { }
71 }
72
73 // -------------------------------------------------------------------------
74 void cpPlugins::Interface::Plugins::
75 GuessPlugins( )
76 {
77   // Create a globbing pattern
78   std::stringstream glob;
79   glob << cpPlugins_LIB_PREFIX << "*" << cpPlugins_LIB_EXT;
80
81   // Update paths and get possible shared libraries
82   this->_ReadPluginsPathsVariable( );
83   for( auto dir : this->m_PluginsPaths )
84   {
85     std::set< std::string > files =
86       cpPlugins::OS::LoadDirContents( dir, false, glob.str( ) );
87     for( auto f : files )
88       try { this->LoadPluginsFile( f ); } catch( ... ) { }
89
90   } // rof
91 }
92
93 // -------------------------------------------------------------------------
94 void cpPlugins::Interface::Plugins::
95 GuessEnvironment( const std::string& dir )
96 {
97   std::stringstream fname;
98   fname << dir << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS;
99   std::string buffer;
100   if( cpPlugins::Read( buffer, fname.str( ) ) )
101   {
102     std::istringstream input( buffer );
103     for( std::string line; std::getline( input, line ); )
104       this->m_PluginsPaths.insert( cpPlugins::CanonicalPath( line ) );
105
106   } // fi
107 }
108
109 // -------------------------------------------------------------------------
110 bool cpPlugins::Interface::Plugins::
111 SaveEnvironment( const std::string& dir )
112 {
113   std::stringstream buffer;
114   for( auto p : this->m_PluginsPaths )
115     buffer << p << std::endl;
116   std::stringstream fname;
117   fname << dir << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS;
118   return( cpPlugins::Write( buffer.str( ), fname.str( ) ) );
119 }
120
121 // -------------------------------------------------------------------------
122 cpPlugins::BaseObjects::ProcessObject::Pointer
123 cpPlugins::Interface::Plugins::
124 CreateFilter( const std::string& category, const std::string& name )
125 {
126   typedef void* ( *_TCreator )( );
127   typedef cpPlugins::BaseObjects::ProcessObject::Pointer _TPtr;
128   _TPtr o = NULL;
129   auto cat = this->m_Filters.find( category );
130   if( cat != this->m_Filters.end( ) )
131   {
132     auto nam = cat->second.find( name );
133     if( nam != cat->second.end( ) )
134     {
135       void* l_hnd = nam->second.second.first;
136       void* f_hnd = nam->second.second.second;
137       if( l_hnd == NULL )
138       {
139         l_hnd = cpPlugins::OS::DLLManager::LoadPlugins( nam->second.first );
140         nam->second.second.first = l_hnd;
141
142       } // fi
143       if( f_hnd == NULL )
144       {
145         f_hnd =
146           cpPlugins::OS::DLLManager::LoadCreator( l_hnd, category, name );
147         nam->second.second.second = f_hnd;
148
149       } // fi
150       _TCreator creator = reinterpret_cast< _TCreator >( f_hnd );
151       if( creator != NULL )
152       {
153         void* a = creator( );
154         o = reinterpret_cast< _TPtr* >( a )->GetPointer( );
155         o->SetName( name );
156         o->SetPluginName( nam->second.first );
157
158       } // fi
159
160     } // fi
161
162   } // fi
163   if( o.IsNull( ) )
164     throw std::runtime_error(
165       std::string( "Could not create a valid ProcessObject of type \"" ) +
166       category + std::string( ":" ) +
167       name + std::string( "\"" )
168       );
169   return( o );
170 }
171
172 // -------------------------------------------------------------------------
173 cpPlugins::Interface::Plugins::
174 Plugins( )
175   : Superclass( )
176 {
177   cpPlugins::OS::DLLManager::TeaseLoadedLibraries( );
178 }
179
180 // -------------------------------------------------------------------------
181 cpPlugins::Interface::Plugins::
182 ~Plugins( )
183 {
184 }
185
186 // -------------------------------------------------------------------------
187 void cpPlugins::Interface::Plugins::
188 PrintSelf( std::ostream& os, itk::Indent indent ) const
189 {
190   for( auto i : this->m_Filters )
191   {
192     os << indent << "+ " << i.first << std::endl;
193     for( auto j : i.second )
194       os << indent << "|----> " << j.first << std::endl;
195
196   } // rof
197 }
198
199 // -------------------------------------------------------------------------
200 void cpPlugins::Interface::Plugins::
201 _ReadPluginsPathsVariable( )
202 {
203 #ifdef cpPlugins_OS_Windows
204   char* p;
205   size_t size;
206   _dupenv_s( &p, &size, cpPlugins_PATHS );
207 #else // cpPlugins_OS_Windows
208   char* p = std::getenv( cpPlugins_PATHS );
209 #endif // cpPlugins_OS_Windows
210   std::stringstream str;
211   if( p != NULL )
212     str << p << cpPlugins_ENV_SEPARATOR;
213   str << ".";
214   std::vector< std::string > tokens;
215   cpPlugins::Tokenize( tokens, str.str( ), cpPlugins_ENV_SEPARATOR );
216   for( auto dir : tokens )
217     this->m_PluginsPaths.insert( cpPlugins::CanonicalPath( dir ) );
218 }
219
220 // eof - $RCSfile$