]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Interface/Plugins.cxx
...
[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         o = reinterpret_cast< _TPtr* >( creator( ) )->GetPointer( );
154         o->SetName( name );
155         o->SetPluginName( nam->second.first );
156
157       } // fi
158
159     } // fi
160
161   } // fi
162   if( o.IsNull( ) )
163     throw std::runtime_error(
164       std::string( "Could not create a valid ProcessObject of type \"" ) +
165       category + std::string( ":" ) +
166       name + std::string( "\"" )
167       );
168   return( o );
169 }
170
171 // -------------------------------------------------------------------------
172 cpPlugins::Interface::Plugins::
173 Plugins( )
174   : Superclass( )
175 {
176   cpPlugins::OS::DLLManager::TeaseLoadedLibraries( );
177 }
178
179 // -------------------------------------------------------------------------
180 cpPlugins::Interface::Plugins::
181 ~Plugins( )
182 {
183 }
184
185 // -------------------------------------------------------------------------
186 void cpPlugins::Interface::Plugins::
187 PrintSelf( std::ostream& os, itk::Indent indent ) const
188 {
189   for( auto i : this->m_Filters )
190   {
191     os << indent << "+ " << i.first << std::endl;
192     for( auto j : i.second )
193       os << indent << "|----> " << j.first << std::endl;
194
195   } // rof
196 }
197
198 // -------------------------------------------------------------------------
199 void cpPlugins::Interface::Plugins::
200 _ReadPluginsPathsVariable( )
201 {
202 #ifdef cpPlugins_OS_Windows
203   char* p;
204   size_t size;
205   _dupenv_s( &p, &size, cpPlugins_PATHS );
206 #else // cpPlugins_OS_Windows
207   char* p = std::getenv( cpPlugins_PATHS );
208 #endif // cpPlugins_OS_Windows
209   std::stringstream str;
210   if( p != NULL )
211     str << p << cpPlugins_ENV_SEPARATOR;
212   str << ".";
213   std::vector< std::string > tokens;
214   cpPlugins::Tokenize( tokens, str.str( ), cpPlugins_ENV_SEPARATOR );
215   for( auto dir : tokens )
216     this->m_PluginsPaths.insert( cpPlugins::CanonicalPath( dir ) );
217 }
218
219 // eof - $RCSfile$