]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Interface/Interface.cxx
...
[cpPlugins.git] / lib / cpPlugins / Interface / Interface.cxx
1 #include <cpPlugins/Interface/Interface.h>
2 #include <algorithm>
3 #include <cstdlib>
4 #include <fstream>
5 #include <sstream>
6 #include <Pluma/Pluma.hpp>
7
8 #ifdef _WIN32
9 #  define PLUGIN_PREFIX ""
10 #  define PLUGIN_EXT ".dll"
11 #else // Linux
12 #  define PLUGIN_PREFIX "lib"
13 #  define PLUGIN_EXT ".so"
14 #endif // _WIN32
15 #define PLUGIN_CONFIG_FILE "plugins.cfg"
16
17 namespace cpPlugins
18 {
19   namespace Interface
20   {
21     struct PathSeparator
22     {
23       bool operator()( char c ) const
24         {
25 #ifdef _WIN32
26           return( c == '\\' || c == '/' );
27 #else // Linux like
28           return( c == '/' );
29 #endif // _WIN32
30         }
31     };
32
33   } // ecapseman
34
35 } // ecapseman
36
37 // -------------------------------------------------------------------------
38 cpPlugins::Interface::Interface::
39 Interface( )
40 {
41   this->m_Pluma = new pluma::Pluma( );
42   this->m_Pluma->acceptProviderType< ProcessObjectProvider >( );
43 }
44
45 // -------------------------------------------------------------------------
46 cpPlugins::Interface::Interface::
47 ~Interface( )
48 {
49   this->UnloadAll( );
50   delete this->m_Pluma;
51 }
52
53 // -------------------------------------------------------------------------
54 bool cpPlugins::Interface::Interface::
55 LoadDefaultConfiguration( const std::string& path )
56 {
57   std::ifstream file( PLUGIN_CONFIG_FILE );
58   if( file )
59   {
60     char buffer[ 1000 ];
61     while( file.getline( buffer, 1000 ) )
62     {
63       // std::string line( buffer );
64       std::istringstream line( buffer );
65       std::string name, folder;
66       std::getline( line, name, '@' );
67       std::getline( line, folder, '@' );
68       std::stringstream path;
69       path << folder << "/" << PLUGIN_PREFIX << name << PLUGIN_EXT;
70       this->Load( path.str( ) );
71
72     } // elihw
73
74     file.close( );
75     return( true );
76   }
77   else
78     return( false );
79 }
80
81 // -------------------------------------------------------------------------
82 bool cpPlugins::Interface::Interface::
83 SaveDefaultConfiguration( const std::string& path )
84 {
85   std::ofstream file( PLUGIN_CONFIG_FILE );
86   if( file )
87   {
88     auto pIt = this->m_LoadedPlugins.begin( );
89     for( ; pIt != this->m_LoadedPlugins.end( ); ++pIt )
90     {
91       auto fIt = pIt->second.begin( );
92       for( ; fIt != pIt->second.end( ); ++fIt )
93         file << *fIt << "@" << pIt->first << std::endl;
94
95     } // rof
96     file.close( );
97     return( true );
98   }
99   else
100     return( false );
101 }
102
103 // -------------------------------------------------------------------------
104 cpPlugins::Interface::Interface::
105 TClasses& cpPlugins::Interface::Interface::
106 GetClasses( )
107 {
108   return( this->m_Classes );
109 }
110
111 // -------------------------------------------------------------------------
112 const cpPlugins::Interface::Interface::
113 TClasses& cpPlugins::Interface::Interface::
114 GetClasses( ) const
115 {
116   return( this->m_Classes );
117 }
118
119 // -------------------------------------------------------------------------
120 cpPlugins::Interface::Interface::
121 TLoadedPlugins& cpPlugins::Interface::Interface::
122 GetLoadedPlugins( )
123 {
124   return( this->m_LoadedPlugins );
125 }
126
127 // -------------------------------------------------------------------------
128 const cpPlugins::Interface::Interface::
129 TLoadedPlugins& cpPlugins::Interface::Interface::
130 GetLoadedPlugins( ) const
131 {
132   return( this->m_LoadedPlugins );
133 }
134
135 // -------------------------------------------------------------------------
136 cpPlugins::Interface::ProcessObject::Pointer
137 cpPlugins::Interface::Interface::
138 CreateObject( const std::string& name ) const
139 {
140   cpPlugins::Interface::ProcessObject::Pointer po = NULL;
141   auto catIt = this->m_Classes.begin( );
142   while( catIt != this->m_Classes.end( ) )
143   {
144     auto classIt = catIt->second.find( name );
145     if( classIt != catIt->second.end( ) )
146     {
147       ProcessObjectProvider* provider =
148         dynamic_cast< ProcessObjectProvider* >(
149           this->m_Providers[ classIt->second ]
150           );
151       if( provider != NULL )
152       {
153         po = provider->create( );
154         po->SetName( name );
155
156       } // fi
157       catIt = this->m_Classes.end( );
158     }
159     else
160       catIt++;
161
162   } // elihw
163
164   return( po );
165 }
166
167 // -------------------------------------------------------------------------
168 bool cpPlugins::Interface::Interface::
169 Load( const std::string& path )
170 {
171   bool ret = true;
172   try
173   {
174     ret = this->m_Pluma->load( path );
175     if( ret )
176     {
177       std::string folder, name;
178       Self::_SepFName( path, folder, name );
179       this->m_LoadedPlugins[ folder ].push_back( name );
180       this->_LoadClasses( );
181
182     } // fi
183   }
184   catch( ... )
185   {
186     ret = false;
187
188   } // yrt
189   return( ret );
190 }
191
192 // -------------------------------------------------------------------------
193 bool cpPlugins::Interface::Interface::
194 Load( const std::string& folder, const std::string& name )
195 {
196   std::string real_folder = folder;
197   PathSeparator sep;
198   if( sep( folder[ folder.size( ) - 1 ] ) )
199     real_folder = folder.substr( 0, folder.size( ) - 1 );
200 #ifdef _WIN32
201   DWORD  retval=0;
202   BOOL   success; 
203   TCHAR  buffer[4096]=TEXT(""); 
204   TCHAR  buf[4096]=TEXT(""); 
205   TCHAR** lppPart={NULL};
206   // Retrieve the full path name for a file. 
207   // The file does not need to exist.
208   retval = GetFullPathName(folder.c_str( ),
209                  4096,
210                  buffer,
211                  lppPart);
212   real_folder = buffer;
213 #else // _WIN32
214   real_folder = std::string( realpath( real_folder.c_str( ), NULL ) );
215 #endif // _WIN32
216   bool ret = true;
217   try
218   {
219     ret = this->m_Pluma->load( real_folder, name );
220     if( ret )
221     {
222       // Update loaded plugins
223       std::string prefix( PLUGIN_PREFIX );
224       std::string ext( PLUGIN_EXT );
225       std::string real_name = name;
226       if( prefix != "" )
227         real_name.replace( real_name.find( prefix ), prefix.size( ), "" );
228       real_name.replace( real_name.find( ext ), ext.size( ), "" );
229       this->m_LoadedPlugins[ real_folder ].push_back( real_name );
230       this->_LoadClasses( );
231
232     } // fi
233   }
234   catch( ... )
235   {
236     ret = false;
237
238   } // yrt
239   return( ret );
240 }
241
242 // -------------------------------------------------------------------------
243 bool cpPlugins::Interface::Interface::
244 LoadFromFolder( const std::string& folder, bool r )
245 {
246   try
247   {
248     std::list< std::string > f = this->m_Pluma->loadFromFolder( folder, r );
249     if( f.size( ) > 0 )
250     {
251       // Update loaded plugins
252       for( auto i = f.begin( ); i != f.end( ); ++i )
253       {
254         std::string folder, name;
255         Self::_SepFName( *i, folder, name );
256         this->m_LoadedPlugins[ folder ].push_back( name );
257
258       } // rof
259
260       // Load classes
261       this->_LoadClasses( );
262       return( true );
263     }
264     else
265       return( false );
266   }
267   catch( ... )
268   {
269     return( false );
270
271   } // yrt
272 }
273
274 // -------------------------------------------------------------------------
275 bool cpPlugins::Interface::Interface::
276 Unload( const std::string& name )
277 {
278   bool ret = true;
279   try
280   {
281     ret = this->m_Pluma->unload( name );
282     if( ret )
283     {
284       this->m_Providers.clear( );
285       this->m_Classes.clear( );
286
287       // TODO: this->m_LoadedPlugins
288
289       this->_LoadClasses( );
290
291     } // fi
292   }
293   catch( ... )
294   {
295     ret = false;
296
297   } // yrt
298   return( ret );
299 }
300
301 // -------------------------------------------------------------------------
302 void cpPlugins::Interface::Interface::
303 UnloadAll( )
304 {
305   try
306   {
307     this->m_Pluma->unloadAll( );
308   }
309   catch( ... )
310   {
311     // Do nothing
312
313   } // yrt
314   this->m_Providers.clear( );
315   this->m_Classes.clear( );
316   this->m_LoadedPlugins.clear( );
317 }
318
319 // -------------------------------------------------------------------------
320 bool cpPlugins::Interface::Interface::
321 IsLoaded( const std::string& name ) const
322 {
323   return( this->m_Pluma->isLoaded( name ) );
324 }
325
326 // -------------------------------------------------------------------------
327 void cpPlugins::Interface::Interface::
328 _LoadClasses( )
329 {
330   this->m_Providers.clear( );
331   this->m_Classes.clear( );
332   this->m_Pluma->getProviders( this->m_Providers );
333
334   // Get reader provider
335   for( unsigned int i = 0; i < this->m_Providers.size( ); ++i )
336   {
337     ProcessObject::Pointer d = this->m_Providers[ i ]->create( );
338     this->m_Classes[ d->GetClassCategory( ) ][ d->GetClassName( ) ] = i;
339
340   } // rof
341 }
342
343 // -------------------------------------------------------------------------
344 void cpPlugins::Interface::Interface::
345 _SepFName( const std::string& path, std::string& folder, std::string& name )
346 {
347   PathSeparator sep;
348
349   // Get absolute path
350   std::string real_path = "";
351 #ifdef _WIN32
352   DWORD  retval=0;
353   BOOL   success; 
354   TCHAR  buffer[4096]=TEXT(""); 
355   TCHAR  buf[4096]=TEXT(""); 
356   TCHAR** lppPart={NULL};
357   // Retrieve the full path name for a file. 
358   // The file does not need to exist.
359   retval = GetFullPathName(path.c_str( ),
360                  4096,
361                  buffer,
362                  lppPart);
363   real_path = buffer;
364 #else // _WIN32
365   real_path = std::string( realpath( path.c_str( ), NULL ) );
366 #endif // _WIN32
367
368   // Get name
369   name = std::string(
370     std::find_if( real_path.rbegin( ), real_path.rend( ), sep ).base( ),
371     real_path.end( )
372     );
373
374   // Get containing folder
375   folder = real_path;
376   folder.replace( folder.find( name ), name.size( ), "" );
377   if( sep( folder[ folder.size( ) - 1 ] ) )
378     folder = folder.substr( 0, folder.size( ) - 1 );
379
380   // Erase prefix and extension from filename
381   std::string prefix( PLUGIN_PREFIX );
382   std::string ext( PLUGIN_EXT );
383   if( prefix != "" )
384     name.replace( name.find( prefix ), prefix.size( ), "" );
385   name.replace( name.find( ext ), ext.size( ), "" );
386 }
387
388 // eof - $RCSfile$