]> Creatis software - bbtk.git/blob - kernel/src/bbtkFactory.cxx
Keywords
[bbtk.git] / kernel / src / bbtkFactory.cxx
1 /*=========================================================================
2                                                                                 
3 Program:   bbtk
4 Module:    $RCSfile: bbtkFactory.cxx,v $
5 Language:  C++
6
7 Date:      $Date: 2008/01/30 12:14:43 $
8 Version:   $Revision: 1.8 $
9                                                                                 
10
11 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
12 l'Image). All rights reserved. See doc/license.txt or
13 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
14
15 This software is distributed WITHOUT ANY WARRANTY; without even
16 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 PURPOSE.  See the above copyright notices for more information.
18
19 =========================================================================*/
20 /**
21  *\file
22  *\brief  Class bbtk::Factory : can load and unload dynamic libraries containing 
23  *        black boxes packages and create instances of the black boxes registered 
24  *       in the packages loaded.
25  */
26 #include "bbtkFactory.h"
27 #include "bbtkMessageManager.h"
28 #include "bbtkConnection.h"
29 #include "bbtkConfigurationFile.h"
30 #include "bbtkUtilities.h"
31
32 #include <sys/stat.h> // for struct stat stFileInfo
33
34 #if defined(_WIN32)
35 #include <direct.h> // for getcwd
36 #endif
37
38
39 // was in gdcm ...
40 /*
41 #ifdef _MSC_VER
42 #   define getcwd _getcwd
43 #endif
44
45 #if defined(_MSC_VER) || defined(__BORLANDC__)
46 #   include <direct.h>
47 #else
48 #   include <unistd.h>
49 #endif
50
51 */
52
53
54 namespace bbtk
55 {
56   typedef Package* (*PackageAccessor)();
57   typedef void (*PackageDeleteFunction)();
58
59
60   //===================================================================
61   /// Default ctor
62   Factory::Factory()
63   {
64     bbtkDebugMessage("Core",7,"Factory::Factory()"<<std::endl);
65   }
66   //===================================================================
67
68   //===================================================================
69   /// Dtor
70   Factory::~Factory()
71   {
72     bbtkDebugMessageInc("Core",7,"Factory::~Factory()"<<std::endl);
73     CloseAllPackages();
74     bbtkDebugDecTab("Core",7);
75   }
76   //===================================================================
77
78
79   //===================================================================
80   void Factory::CloseAllPackages()
81   {
82     bbtkDebugMessageInc("Core",7,"Factory::CloseAllPackages()"<<std::endl);
83     while (mPackageMap.begin() != mPackageMap.end())
84       {
85         PackageMapType::iterator i = mPackageMap.begin();
86         ClosePackage(i);
87       }
88     bbtkDebugDecTab("Core",7);
89   }
90   //===================================================================
91
92   //===================================================================
93   void Factory::Reset()
94   {
95     bbtkDebugMessageInc("Core",7,"Factory::Reset()"<<std::endl);
96     CloseAllPackages();
97     bbtkDebugDecTab("Core",7);
98   }
99   //===================================================================
100
101
102 // ===================================================================================
103
104   bool Factory::DoLoadPackage(std::string libname,
105                               std::string pkgname,
106                               std::string path,
107                               bool verbose)
108   {
109
110 #if defined(__GNUC__)
111
112         void *handler;
113         handler = dlopen(libname.c_str(),
114                                      BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
115         if (!handler)
116         {
117         // The following is *NOT* a debug time message :
118         // It's a user intended message.
119         // Please don't remove it.
120           if (verbose) {
121             std::cout <<"[" <<libname<<"] can't be open" << std::endl;
122             std::cout << "   " <<dlerror() << std::endl;
123           }
124           return false; // try next path
125         }
126
127         // The following is *NOT* a debug time message :
128         // It's a user intended message.
129         // Please don't remove it.
130         if (verbose)
131           std::cout <<"   -->[" <<libname<<"] found" << std::endl;
132
133       // Loads the Package accessor
134
135         std::string getpackname(pkgname);
136         getpackname += "GetPackage";
137         void *getpack = dlsym(handler, getpackname.c_str());
138         if (!getpack)
139         {
140           dlclose(handler);
141           bbtkError("GetPackage : could not load package \""<<pkgname
142                    <<"\" [symbol "<<getpackname<<"] :"<<dlerror());
143         }
144
145         // Verifies that the Package delete function is present
146         std::string delfname(pkgname);
147         delfname += "DeletePackage";
148         void *delf = dlsym(handler, delfname.c_str());
149         if (!delf)
150         {
151           dlclose(handler);
152           bbtkError("DeletePackage : could not load package \""<<pkgname
153                     <<"\" [symbol "<<delfname<<"] :"<<dlerror());
154         }
155
156 #elif defined(_WIN32)
157
158         HINSTANCE handler;
159
160         SetErrorMode(0);
161         handler = LoadLibrary(libname.c_str());
162         if (!handler){
163           if (verbose)
164         // The following is *NOT* a debug time message :
165         // It's a user intended message.
166         // Please don't remove it.
167             std::cout <<"   no handler for [" <<libname<<"];" << std::endl;
168           return false;// Problem with the found library
169         }
170         if (verbose)
171           std::cout <<"   --->[" <<libname<<"] found" << std::endl;
172
173     // Loads the Package accessor
174
175         std::string getpackname(pkgname);
176         getpackname += "GetPackage";
177         void *getpack = GetProcAddress(handler, getpackname.c_str());
178         if (!getpack)
179         {
180           FreeLibrary(handler);
181           bbtkError("[1]could not load package \""<<pkgname
182           <<"\" : "<<getpackname<<" symbol not found (is it a bbtk package lib ?)");
183           // look how to get the error message on win
184               //<<dlerror());
185         }
186         // Verifies that the Package delete function is present
187         std::string delfname(pkgname);
188         delfname += "DeletePackage";
189         void *delf = GetProcAddress(handler, delfname.c_str());
190         if (!delf)
191         {
192           FreeLibrary(handler);
193           bbtkError("[2]could not load package \""<<pkgname
194                      <<"\" : "<<delfname<<" symbol not found (is it a bbtk package lib ?)");
195           // look how to get the error message on win
196           //<<dlerror());
197         }
198 #else
199         bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
200 #endif
201
202     // Stores the package
203         PackageInfoType pack;
204         pack.mDynamicLibraryHandler = handler;
205     // Invokes the accessor to the PackageUnit pointer
206         pack.mPackage = ((PackageAccessor)getpack)();
207
208         mPackageMap[pkgname] = pack;
209
210     // Test bbtk build version ok
211         if ( pack.mPackage->GetBBTKVersion() != bbtk::GetVersion() )
212         {
213           std::string v(pack.mPackage->GetBBTKVersion());
214           UnLoadPackage(pkgname);
215           bbtkError(" package build with bbtk version "
216                     << v
217                     << " whereas application build with version "
218                     << bbtk::GetVersion());
219         }
220
221         std::string separator =
222         ConfigurationFile::GetInstance().Get_file_separator ();
223         //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
224         std::string docreldoc = separator + "packages" + separator + pkgname
225          + separator + "bbdoc" + separator + "index.html";
226         std::string reldoc = ".." + separator + ".." + separator
227          + ".." + docreldoc;
228         std::string doc = path + separator + ".." + separator
229          + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
230          + docreldoc;
231
232         pack.mPackage->SetDocURL(doc);
233         pack.mPackage->SetDocRelativeURL(reldoc);
234
235     //===================================================================
236         bbtkMessage("Output",2,pack.mPackage->GetName()<<" "
237            <<pack.mPackage->GetVersion()
238            <<" (bbtk "
239            <<pack.mPackage->GetBBTKVersion()<<") "
240            <<pack.mPackage->GetAuthor() << " Keyword(s) :"
241            <<pack.mPackage->GetKeyword()
242            <<std::endl);
243         bbtkMessage("Output",2,pack.mPackage->GetDescription()<<std::endl);
244     //===================================================================
245
246         bbtkDebugDecTab("Core",7);
247         return true;
248   }
249
250   //===================================================================
251   /// \brief Loads a package.
252   ///
253   /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
254   /// Tries to open the dynamic library :
255   /// - "libbb<name>.so" for linux systems,
256   /// - "bb<name>.dll" for windows systems.
257   /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
258   /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
259   /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
260
261   /// now, filename is only the last name (no longer the full name!)
262   /// it will be searched within *all* the paths given in bbtk_config.xml
263
264   /// verbose = true (set by "config v") displays the loading process
265
266   void Factory::LoadPackage( const std::string& name,
267                              bool use_configuration_file, bool verbose)
268   {
269   // Note : in the following :
270   // name : the user supplied name
271   //      - abreviated name    e.g.       pkg   pkg.so   libbpkg   libbbpkg.so
272   //      - relative full name e.g.       ./libbbpkg.so   ../../libbbpkg.so
273   //      - absolute full name e.g.       /home/usrname/proj/lib/libbbpkg.so
274   //          same for Windows, with      c:, d: ...
275   //
276   // lastname : string before the last / (if any), or user supplied name
277
278     bbtkDebugMessageInc("Core",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
279     bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
280     bbtkMessage("Debug",1,"use_configuration_file ["
281                  << use_configuration_file << "]" << std::endl);
282
283     std::vector<std::string> package_paths;
284     std::string libname;  // full path library name
285     std::string pkgname;  // e.g. libbb<pkgname>.so
286
287     std::string upath;
288     pkgname = Utilities::ExtractPackageName(name,upath);
289
290     bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
291     bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
292
293     // no loading package if already loaded
294     PackageMapType::iterator iUnload;
295     iUnload = mPackageMap.find(pkgname);
296     if (iUnload != mPackageMap.end())
297     {
298       bbtkMessage("Output",2,"["<< pkgname <<"] already loaded" << std::endl);
299       return;
300     }
301
302 // =================================================
303 // The following structure was checked to work
304 // with any type of relative/absolute path.
305 // Please don't modify it without checking
306 // *all* the cases. JP
307 //==================================================
308
309 //std::cout << "upath [" << upath << "]" << std::endl;
310
311     bool ok = false;
312     bool foundFile = false;
313
314     // If path provided by user will be the first scanned :
315     // push it into vector of paths
316     if (upath.length()>0)   // ------------------------------------- check user supplied location
317     {
318        if (name[0] != '.' && name[0] != '/' && name[1]!= ':')
319        {
320           bbtkError("Use absolute or relative path name! ["<<name<<"] is an illegal name");
321           return;
322        }
323
324       // std::string path = Utilities::ExpandLibName(upath, verbose);
325        std::string path = Utilities::ExpandLibName(name, verbose); // keep last item, here.
326          
327        if (path != "")
328        {
329           std::string p2;
330           Utilities::ExtractPackageName(path,p2);
331           //libname = Utilities::MakeLibnameFromPath(path, pkgname);
332           libname = Utilities::MakeLibnameFromPath(p2, pkgname); // remove last item
333           // Check if library exists
334           if ( !Utilities::FileExists(libname) )
335           {
336           // The following is *NOT* a debug time message :
337           // It's a user intended message.
338           // Please don't remove it.
339              if (verbose)
340                 std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
341           }
342           else
343           {
344              ok = DoLoadPackage( libname, pkgname, path, verbose);         
345           }
346        }
347        else
348        {
349           bbtkError("Path ["<<upath<<"] doesn't exist");
350           return;
351        }
352     }
353     else     // ----------------------------------------------------- iterate on the paths  
354     {
355
356     std::string path;
357     package_paths = ConfigurationFile::GetInstance().Get_package_paths();
358     std::vector<std::string>::iterator i;
359     for (i=package_paths.begin();i!=package_paths.end();++i)
360     {
361         foundFile = false;
362         path = *i;
363
364         // we *really* want '.' to be the current working directory
365         if (path == ".")
366         {
367           char buf[2048]; // for getcwd
368           char * currentDir = getcwd(buf, 2048);
369           std::string cwd(currentDir);
370           path = currentDir;
371         }
372
373         libname = Utilities::MakeLibnameFromPath(path, pkgname);
374
375         bbtkMessage("Debug",2,"-> Trying to load [" << libname << "]" <<std::endl);
376
377       // Check if library exists           
378         if ( !Utilities::FileExists(libname) )
379         {
380         // The following is *NOT* a debug time message :
381         // It's a user intended message.
382         // Please don't remove it.
383            if (verbose)
384               std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
385            continue;  // try next path
386         }
387         foundFile = true; 
388
389       // Try to Load the library
390
391         ok = DoLoadPackage( libname, pkgname, path, verbose);
392         if (ok)
393         {
394            bbtkMessage("Debug",2,"   OK"<<std::endl);
395            break; // a package was found; we stop iterating
396         }
397     } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
398
399 }
400
401     if( !ok )  // nothing was loaded
402     {
403       if (!foundFile)
404       {
405         bbtkError("could not find package ["<<pkgname<< "]");
406       }
407       else
408       {
409 #if defined(__GNUC__)
410         bbtkError("could not load package ["<< pkgname
411                   <<"] :" << std::endl << "   " << dlerror());
412 #elif defined(_WIN32)
413         bbtkError("could not load package ["<<pkgname
414                  <<"] : " << std::endl << "   " <<libname<<" not found");
415
416     // look how to get the error message on win
417     //<<dlerror());
418     // it is the bordel !! (the bloody fucking bordel, you mean?)
419     // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
420 #endif
421       }
422     }
423     bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
424
425   }
426
427   //===================================================================
428   /// \brief UnLoads a package.
429   ///
430   /// The package must have been previously loaded by LoadPackage.
431   /// If the entry is found in the map, calls ClosePackage
432  void Factory::UnLoadPackage( const std::string& name )
433  {
434     bbtkDebugMessageInc("Core",7,"Factory::UnLoadPackage(\""
435                        <<name<<"\")"<<std::endl);
436   
437     PackageMapType::iterator i;
438     i = mPackageMap.find(name);
439     if (i == mPackageMap.end()) 
440     {
441       bbtkError("cannot unload package \""<<name
442                 <<"\" : package not loaded !");
443     }
444     ClosePackage(i);
445     bbtkDebugDecTab("Core",7);
446   }
447   //===================================================================
448
449
450   //===================================================================
451   /// \brief Close the package referenced by the iterator 
452   ///
453   /// If it is a dynamically loaded package 
454   /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
455   /// - Closes the dynamic library
456   /// - Erases the package entry in the packages map
457   ///
458   /// Else simply erases the package entry in the packages map
459   void Factory::ClosePackage(PackageMapType::iterator& i) 
460   {   
461      bbtkDebugMessageInc("Core",7,"Factory::ClosePackage(\""
462                          <<i->second.mPackage->GetName()
463                         <<"\")"<<std::endl);
464
465      if (i->second.mDynamicLibraryHandler) 
466      {
467  
468       // If it is a dynamically loaded package
469       // Loads the Package delete function
470
471         std::string delfname(i->second.mPackage->GetName());
472         delfname += "DeletePackage";
473 #if defined(__GNUC__)     
474         void *delf = dlsym(i->second.mDynamicLibraryHandler, delfname.c_str());
475         if (!delf)
476         {
477            bbtkError("could not close package \""
478                      <<i->second.mPackage->GetName()
479                      <<"\" :"<<dlerror());
480         }    
481 #elif defined(_WIN32)
482    void *delf = GetProcAddress(i->second.mDynamicLibraryHandler, 
483                                  delfname.c_str());
484      if (!delf)
485      {  
486        bbtkError("could not close package \""
487                 <<i->second.mPackage->GetName()
488                 <<"\" : "<<delfname
489                 <<" symbol not found (how did you open it ???");
490                //<<"\" :"<<dlerror());
491      }    
492 #endif     
493
494    // deletes the package
495    ((PackageDeleteFunction)delf)();
496
497    // closes the dl handler
498 #if defined(__GNUC__)  
499     dlclose(i->second.mDynamicLibraryHandler);  
500 #elif defined(_WIN32)
501
502     FreeLibrary(i->second.mDynamicLibraryHandler);
503 #endif
504     }
505     else 
506     {  
507        // If it is a manually inserted package 
508        delete i->second.mPackage;
509     }
510
511     // remove the entry in the map
512     mPackageMap.erase(i);
513     bbtkDebugDecTab("Core",7);
514  }
515   //===================================================================
516
517
518
519   //===================================================================  
520   /// Displays the list of packages loaded
521   void Factory::PrintPackages(bool details, bool adaptors) const
522   {
523     bbtkDebugMessageInc("Core",9,"Factory::PrintPackages"<<std::endl);
524
525     PackageMapType::const_iterator i;
526     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
527     {
528       bbtkMessage("Help",1, i->first << std::endl);
529       if (details) {
530          i->second.mPackage->PrintBlackBoxes(false,adaptors);
531       }
532     }
533
534     bbtkDebugDecTab("Core",9);
535   }
536   //===================================================================
537
538   //===================================================================  
539   /// Displays help on a package
540   void Factory::HelpPackage(const std::string& name, bool adaptors) const
541   {
542     bbtkDebugMessageInc("Core",9,"Factory::HelpPackage(\""<<name<<"\")"
543                         <<std::endl);
544
545     PackageMapType::const_iterator i = mPackageMap.find(name);
546     if ( i != mPackageMap.end() ) 
547       {
548       bbtkMessage("Help",1, "Package "<<i->first<<" ");
549       
550       if (i->second.mPackage->GetVersion().length()>0)
551         bbtkMessageCont("Help",1,"v" <<i->second.mPackage->GetVersion());
552         
553       if (i->second.mPackage->GetAuthor().length()>0)
554         bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetAuthor());
555         
556       if (i->second.mPackage->GetKeyword().length()>0)
557         bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetKeyword());        
558         
559       bbtkMessageCont("Help",1,std::endl);
560       bbtkIncTab("Help",1);
561       bbtkMessage("Help",1,i->second.mPackage->GetDescription()<<std::endl);
562       if (i->second.mPackage->GetNumberOfBlackBoxes()>0) 
563         {
564           bbtkMessage("Help",1, "Black boxes : "<<std::endl);
565           i->second.mPackage->PrintBlackBoxes(true,adaptors);
566         }
567       else 
568         {
569           bbtkMessage("Help",1, "No black boxes"<<std::endl);
570         }
571       bbtkDecTab("Help",1);
572       }
573     else 
574       {
575       bbtkDebugDecTab("Core",9);
576       bbtkError("package \""<<name<<"\" unknown");
577       }
578     
579     bbtkDebugDecTab("Core",9);
580   }
581   //===================================================================
582
583   //===================================================================
584   /// Prints help on the black box of type <name>
585   void Factory::HelpBlackBox(const std::string& name, bool full) const
586   {
587     bbtkDebugMessageInc("Core",9,"Factory::HelpBlackBox(\""<<name<<"\")"
588                         <<std::endl);
589
590     bool found = false;
591     PackageMapType::const_iterator i;
592     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
593       {
594       if (i->second.mPackage->ContainsBlackBox(name)) 
595         {
596           i->second.mPackage->HelpBlackBox(name,full);
597           found = true;
598         }
599       }
600     
601     bbtkDebugDecTab("Core",9);
602     if (!found) 
603       {
604       bbtkError("No package of the factory contains any black box <"
605                  <<name<<">");
606       }
607   }  
608   //===================================================================
609
610
611   //=================================================================== 
612   /// Inserts a package in the factory
613   void Factory::InsertPackage( Package* p )
614   {
615     bbtkDebugMessageInc("Core",9,"Factory::InsertPackage(\""<<
616                         p->GetName()<<"\")"<<std::endl);
617
618     PackageInfoType pack;
619     pack.mDynamicLibraryHandler = 0;
620     
621     pack.mPackage = p;
622
623     mPackageMap[p->GetName()] = pack;
624     bbtkDebugDecTab("Core",9);
625   }
626   //===================================================================
627   
628   //=================================================================== 
629   /// Removes a package from the factory (and deletes it)
630   void Factory::RemovePackage( Package* p )
631   {
632     bbtkDebugMessageInc("Core",9,"Factory::RemovePackage(\""<<
633                         p->GetName()<<"\")"<<std::endl);
634
635     PackageMapType::iterator i;
636     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
637       {
638          if (i->second.mPackage == p) break;
639       };
640     
641     if (i!=mPackageMap.end())
642       {
643       ClosePackage(i);
644       }
645     else 
646       {
647       bbtkError("Factory::RemovePackage(\""<<
648                  p->GetName()<<"\") : package absent from factory");
649       }
650
651     bbtkDebugDecTab("Core",9);
652   }
653   //===================================================================
654   
655
656   //===================================================================
657   /// Creates an instance of a black box of type <type> with name <name>
658   BlackBox* Factory::NewBlackBox(const std::string& type, 
659                                  const std::string& name) const
660   {
661     bbtkDebugMessageInc("Core",7,"Factory::NewBlackBox(\""
662                         <<type<<"\",\""<<name<<"\")"<<std::endl);
663
664     BlackBox* b = 0; 
665     PackageMapType::const_iterator i;
666     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
667       {
668       b = i->second.mPackage->NewBlackBox(type,name);
669       if (b) break; 
670       }
671     if (!b) 
672       {
673        bbtkError("black box type \""<<type<<"\" unknown");
674       } 
675
676     bbtkDebugDecTab("Core",7);
677     return b;
678   }
679   //===================================================================
680
681   //===================================================================
682   /// Creates an instance of a black box of type <type> with name <name>
683   BlackBox* Factory::NewAdaptor(TypeInfo typein,
684                      TypeInfo typeout,
685                      const std::string& name) const
686   {
687     bbtkDebugMessageInc("Core",8,"Factory::NewAdaptor(<"
688                         <<TypeName(typein)<<">,<"
689                         <<TypeName(typeout)<<">,\""
690                         <<name<<"\")"<<bbtkendl);
691
692
693     BlackBox* b = 0; 
694     PackageMapType::const_iterator i;
695     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
696       {
697       b = i->second.mPackage->NewAdaptor(typein,typeout,name);
698       if (b) break; 
699       }
700     if (!b) 
701       {
702       bbtkError("no <"
703           <<TypeName(typein)<<"> to <"
704           <<TypeName(typeout)
705           <<"> adaptor available");
706       } 
707     
708     bbtkDebugDecTab("Core",7);
709     return b; 
710   }
711   //===================================================================
712
713   //===================================================================
714   /// Creates an instance of a connection
715   Connection* Factory::NewConnection(BlackBox* from,
716                                      const std::string& output,
717                                      BlackBox* to,
718                                      const std::string& input) const
719   {
720     bbtkDebugMessage("Core",7,"Factory::NewConnection(\""
721                       <<from->bbGetName()<<"\",\""<<output<<"\",\""
722                       <<to->bbGetName()<<"\",\""<<input
723                       <<"\")"<<std::endl);
724     
725     return new Connection(from,output,to,input);
726     /*  
727        Connection* c;
728     // !!! WARNING : WE NEED TO TEST THE TYPE NAME EQUALITY 
729     // BECAUSE IN DIFFERENT DYN LIBS THE type_info EQUALITY CAN 
730     // BE FALSE (DIFFERENT INSTANCES !)
731   
732     std::string t1 ( from->bbGetOutputType(output).name() );
733     std::string t2 ( to->bbGetInputType(input).name() );
734
735
736     if ( t1 == t2 ) 
737        //from->bbGetOutputType(output) ==
738        // to->bbGetInputType(input) )
739       {
740          c = new Connection(from,output,to,input);
741       }
742     else 
743       {
744          //   std::cout << "Adaptive connection "<<std::endl;
745          std::string name;
746          name = from->bbGetName() + "." + output + "-" 
747                                   + to->bbGetName() + "." + input; 
748
749          BlackBox* b = 0; 
750          PackageMapType::const_iterator i;
751          for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
752          {
753              b = i->second.mPackage->NewAdaptor(from->bbGetOutputType(output),
754                                                   to->bbGetInputType(input),
755                                                   name);
756              if (b) break; 
757          } 
758          if (!b)  
759          {  
760             bbtkError("did not find any <"
761                        <<TypeName(from->bbGetOutputType(output))
762                        <<"> to <"
763                        <<TypeName(to->bbGetInputType(input))
764                        <<"> adaptor");
765          } 
766          c = new AdaptiveConnection(from,output,to,input,b);
767       }
768       bbtkDebugDecTab("Core",7);
769     
770       return c;
771     */
772   }
773   //===================================================================
774
775
776
777   //===================================================================
778   const Package* Factory::GetPackage(const std::string& name) const
779   {
780     bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
781                          <<std::endl);
782
783     PackageMapType::const_iterator i = mPackageMap.find(name);
784     if ( i != mPackageMap.end() ) 
785     {
786       bbtkDebugDecTab("Core",9); 
787       return i->second.mPackage;
788     }
789     else 
790     {
791        bbtkDebugDecTab("Core",9);
792        bbtkError("package \""<<name<<"\" unknown");
793     }
794     
795     bbtkDebugDecTab("Core",9);  
796   }
797   //===================================================================
798   
799   //===================================================================
800   Package* Factory::GetPackage(const std::string& name) 
801   {
802     bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
803                          <<std::endl);
804
805     PackageMapType::const_iterator i = mPackageMap.find(name);
806     if ( i != mPackageMap.end() ) 
807     {
808       bbtkDebugDecTab("Core",9); 
809       return i->second.mPackage;
810     }
811     else 
812     {
813        bbtkDebugDecTab("Core",9);
814        bbtkError("package \""<<name<<"\" unknown");
815     }
816     
817     bbtkDebugDecTab("Core",9);  
818   }
819   //===================================================================
820
821   //===================================================================
822   void Factory::WriteDotFilePackagesList(FILE *ff)
823   {
824     bbtkDebugMessageInc("Core",9,"Factory::WriteDotFilePackagesList()"
825                          <<std::endl);
826
827     fprintf( ff , "\n");
828     fprintf( ff , "subgraph cluster_FACTORY {\n");
829     fprintf( ff , "  label = \"PACKAGES\"%s\n",  ";");
830     fprintf( ff , "  style=filled%s\n",";");
831     fprintf( ff , "  color=lightgrey%s\n",";");
832     fprintf( ff , "  rankdir=TB%s\n",";");
833
834     std::string url;
835     PackageMapType::const_iterator i;
836     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
837     {
838        url=GetPackage(i->first)->GetDocURL();
839        fprintf(ff,"  %s [shape=ellipse, URL=\"%s\"]%s\n",i->first.c_str(),url.c_str(),";" );
840     }
841     fprintf( ff , "}\n\n");
842     bbtkDebugDecTab("Core",9);
843   }
844   //===================================================================
845
846
847  void Factory::ShowGraphTypes(const std::string& name) const
848  {
849    bool found = false;
850    PackageMapType::const_iterator i;
851    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
852    {
853       if (i->second.mPackage->ContainsBlackBox(name)) 
854       {
855          std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
856
857             // Don't pollute the file store with  "doc_tmp" directories ...    
858          std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
859          std::string directory = "\"" + default_doc_dir + separator + "doc_tmp"  +separator + "\"";
860          std::string filename2 =  default_doc_dir + separator + "doc_tmp" + separator + "tmp.html"; 
861
862 #if defined(_WIN32)  
863         std::string command("start \"Titre\" /D ");
864 #else 
865         std::string command("gnome-open ");
866 #endif
867         command=command + directory +" tmp.html";
868         FILE *ff;
869         ff=fopen(filename2.c_str(),"w");
870
871         fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
872         fprintf(ff,"  window.location=\"%s#%s\";\n" , i->second.mPackage->GetDocURL().c_str(),name.c_str() );
873         fprintf(ff,"//--></script></head><body></body></html>\n");
874
875
876         //fprintf(ff, "<a  href=\"%s#%s\">Link</a>\n", i->second.mPackage->GetDocURL().c_str(),name.c_str() );
877         fclose(ff);
878         system( command.c_str() );      
879         found = true;
880      }
881    }
882     
883    bbtkDebugDecTab("Core",9);
884    if (!found) 
885    {
886       bbtkError("No package of the factory contains any black box <"
887                 <<name<<">");
888    }
889  }
890
891 }
892