]> Creatis software - bbtk.git/blob - kernel/src/bbtkFactory.cxx
We can now use absolute/realtive path for scripts, as well as the '* notation'
[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/29 10:12:45 $
8 Version:   $Revision: 1.4 $
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()
241            <<std::endl);
242         bbtkMessage("Output",2,pack.mPackage->GetDescription()<<std::endl);
243     //===================================================================
244
245         bbtkDebugDecTab("Core",7);
246         return true;
247   }
248
249   //===================================================================
250   /// \brief Loads a package.
251   ///
252   /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
253   /// Tries to open the dynamic library :
254   /// - "libbb<name>.so" for linux systems,
255   /// - "bb<name>.dll" for windows systems.
256   /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
257   /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
258   /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
259
260   /// now, filename is only the last name (no longer the full name!)
261   /// it will be searched within *all* the paths given in bbtk_config.xml
262
263   /// verbose = true (set by "config v") displays the loading process
264
265   void Factory::LoadPackage( const std::string& name,
266                              bool use_configuration_file, bool verbose)
267   {
268   // Note : in the following :
269   // name : the user supplied name
270   //      - abreviated name    e.g.       pkg   pkg.so   libbpkg   libbbpkg.so
271   //      - relative full name e.g.       ./libbbpkg.so   ../../libbbpkg.so
272   //      - absolute full name e.g.       /home/usrname/proj/lib/libbbpkg.so
273   //          same for Windows, with      c:, d: ...
274   //
275   // lastname : string before the last / (if any), or user supplied name
276
277     bbtkDebugMessageInc("Core",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
278     bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
279     bbtkMessage("Debug",1,"use_configuration_file ["
280                  << use_configuration_file << "]" << std::endl);
281
282     std::vector<std::string> package_paths;
283     std::string libname;  // full path library name
284     std::string pkgname;  // e.g. libbb<pkgname>.so
285
286     std::string upath;
287     pkgname = Utilities::ExtractPackageName(name,upath);
288
289     bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
290     bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
291
292     // no loading package if already loaded
293     PackageMapType::iterator iUnload;
294     iUnload = mPackageMap.find(pkgname);
295     if (iUnload != mPackageMap.end())
296     {
297       bbtkMessage("Output",2,"["<< pkgname <<"] already loaded" << std::endl);
298       return;
299     }
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        if (path != "")
327        {
328           std::string p2;
329           Utilities::ExtractPackageName(path,p2);
330           //libname = Utilities::MakeLibnameFromPath(path, pkgname);
331           libname = Utilities::MakeLibnameFromPath(p2, pkgname); // remove last item
332           // Check if library exists
333           if ( !Utilities::FileExists(libname) )
334           {
335           // The following is *NOT* a debug time message :
336           // It's a user intended message.
337           // Please don't remove it.
338              if (verbose)
339                 std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
340           }
341           else
342           {
343              ok = DoLoadPackage( libname, pkgname, path, verbose);         
344           }
345        }
346        else
347        {
348           bbtkError("Path ["<<upath<<"] doesn't exist");
349           return;
350        }
351     }
352     else     // ----------------------------------------------------- iterate on the paths  
353     {
354
355     std::string path;
356     package_paths = ConfigurationFile::GetInstance().Get_package_paths();
357     std::vector<std::string>::iterator i;
358     for (i=package_paths.begin();i!=package_paths.end();++i)
359     {
360         foundFile = false;
361         path = *i;
362
363         // we *really* want '.' to be the current working directory
364         if (path == ".")
365         {
366           char buf[2048]; // for getcwd
367           char * currentDir = getcwd(buf, 2048);
368           std::string cwd(currentDir);
369           path = currentDir;
370         }
371
372         libname = Utilities::MakeLibnameFromPath(path, pkgname);
373
374         bbtkMessage("Debug",2,"-> Trying to load [" << libname << "]" <<std::endl);
375
376       // Check if library exists           
377         if ( !Utilities::FileExists(libname) )
378         {
379         // The following is *NOT* a debug time message :
380         // It's a user intended message.
381         // Please don't remove it.
382            if (verbose)
383               std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
384            continue;  // try next path
385         }
386         foundFile = true; 
387
388       // Try to Load the library
389
390         ok = DoLoadPackage( libname, pkgname, path, verbose);
391         if (ok)
392         {
393            bbtkMessage("Debug",2,"   OK"<<std::endl);
394            break; // a package was found; we stop iterating
395         }
396     } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
397
398 }
399
400     if( !ok )  // nothing was loaded
401     {
402       if (!foundFile)
403       {
404         bbtkError("could not find package ["<<pkgname<< "]");
405       }
406       else
407       {
408 #if defined(__GNUC__)
409         bbtkError("could not load package ["<< pkgname
410                   <<"] :" << std::endl << "   " << dlerror());
411 #elif defined(_WIN32)
412         bbtkError("could not load package ["<<pkgname
413                  <<"] : " << std::endl << "   " <<libname<<" not found");
414
415     // look how to get the error message on win
416     //<<dlerror());
417     // it is the bordel !! (the bloody fucking bordel, you mean?)
418     // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
419 #endif
420       }
421     }
422     bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
423
424   }
425
426   //===================================================================
427   /// \brief UnLoads a package.
428   ///
429   /// The package must have been previously loaded by LoadPackage.
430   /// If the entry is found in the map, calls ClosePackage
431  void Factory::UnLoadPackage( const std::string& name )
432  {
433     bbtkDebugMessageInc("Core",7,"Factory::UnLoadPackage(\""
434                        <<name<<"\")"<<std::endl);
435   
436     PackageMapType::iterator i;
437     i = mPackageMap.find(name);
438     if (i == mPackageMap.end()) 
439     {
440       bbtkError("cannot unload package \""<<name
441                 <<"\" : package not loaded !");
442     }
443     ClosePackage(i);
444     bbtkDebugDecTab("Core",7);
445   }
446   //===================================================================
447
448
449   //===================================================================
450   /// \brief Close the package referenced by the iterator 
451   ///
452   /// If it is a dynamically loaded package 
453   /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
454   /// - Closes the dynamic library
455   /// - Erases the package entry in the packages map
456   ///
457   /// Else simply erases the package entry in the packages map
458   void Factory::ClosePackage(PackageMapType::iterator& i) 
459   {   
460      bbtkDebugMessageInc("Core",7,"Factory::ClosePackage(\""
461                          <<i->second.mPackage->GetName()
462                         <<"\")"<<std::endl);
463
464      if (i->second.mDynamicLibraryHandler) 
465      {
466  
467       // If it is a dynamically loaded package
468       // Loads the Package delete function
469
470         std::string delfname(i->second.mPackage->GetName());
471         delfname += "DeletePackage";
472 #if defined(__GNUC__)     
473         void *delf = dlsym(i->second.mDynamicLibraryHandler, delfname.c_str());
474         if (!delf)
475         {
476            bbtkError("could not close package \""
477                      <<i->second.mPackage->GetName()
478                      <<"\" :"<<dlerror());
479         }    
480 #elif defined(_WIN32)
481    void *delf = GetProcAddress(i->second.mDynamicLibraryHandler, 
482                                  delfname.c_str());
483      if (!delf)
484      {  
485        bbtkError("could not close package \""
486                 <<i->second.mPackage->GetName()
487                 <<"\" : "<<delfname
488                 <<" symbol not found (how did you open it ???");
489                //<<"\" :"<<dlerror());
490      }    
491 #endif     
492
493    // deletes the package
494    ((PackageDeleteFunction)delf)();
495
496    // closes the dl handler
497 #if defined(__GNUC__)  
498     dlclose(i->second.mDynamicLibraryHandler);  
499 #elif defined(_WIN32)
500
501     FreeLibrary(i->second.mDynamicLibraryHandler);
502 #endif
503     }
504     else 
505     {  
506        // If it is a manually inserted package 
507        delete i->second.mPackage;
508     }
509
510     // remove the entry in the map
511     mPackageMap.erase(i);
512     bbtkDebugDecTab("Core",7);
513  }
514   //===================================================================
515
516
517
518   //===================================================================  
519   /// Displays the list of packages loaded
520   void Factory::PrintPackages(bool details, bool adaptors) const
521   {
522     bbtkDebugMessageInc("Core",9,"Factory::PrintPackages"<<std::endl);
523
524     PackageMapType::const_iterator i;
525     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
526     {
527       bbtkMessage("Help",1, i->first << std::endl);
528       if (details) {
529          i->second.mPackage->PrintBlackBoxes(false,adaptors);
530       }
531     }
532
533     bbtkDebugDecTab("Core",9);
534   }
535   //===================================================================
536
537   //===================================================================  
538   /// Displays help on a package
539   void Factory::HelpPackage(const std::string& name, bool adaptors) const
540   {
541     bbtkDebugMessageInc("Core",9,"Factory::HelpPackage(\""<<name<<"\")"
542                         <<std::endl);
543
544     PackageMapType::const_iterator i = mPackageMap.find(name);
545     if ( i != mPackageMap.end() ) 
546       {
547       bbtkMessage("Help",1, "Package "<<i->first<<" ");
548       if (i->second.mPackage->GetVersion().length()>0)
549         bbtkMessageCont("Help",1,"v" <<i->second.mPackage->GetVersion());
550       if (i->second.mPackage->GetAuthor().length()>0)
551         bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetAuthor());
552       bbtkMessageCont("Help",1,std::endl);
553       bbtkIncTab("Help",1);
554       bbtkMessage("Help",1,i->second.mPackage->GetDescription()<<std::endl);
555       if (i->second.mPackage->GetNumberOfBlackBoxes()>0) 
556         {
557           bbtkMessage("Help",1, "Black boxes : "<<std::endl);
558           i->second.mPackage->PrintBlackBoxes(true,adaptors);
559         }
560       else 
561         {
562           bbtkMessage("Help",1, "No black boxes"<<std::endl);
563         }
564       bbtkDecTab("Help",1);
565       }
566     else 
567       {
568       bbtkDebugDecTab("Core",9);
569       bbtkError("package \""<<name<<"\" unknown");
570       }
571     
572     bbtkDebugDecTab("Core",9);
573   }
574   //===================================================================
575
576   //===================================================================
577   /// Prints help on the black box of type <name>
578   void Factory::HelpBlackBox(const std::string& name, bool full) const
579   {
580     bbtkDebugMessageInc("Core",9,"Factory::HelpBlackBox(\""<<name<<"\")"
581                         <<std::endl);
582
583     bool found = false;
584     PackageMapType::const_iterator i;
585     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
586       {
587       if (i->second.mPackage->ContainsBlackBox(name)) 
588         {
589           i->second.mPackage->HelpBlackBox(name,full);
590           found = true;
591         }
592       }
593     
594     bbtkDebugDecTab("Core",9);
595     if (!found) 
596       {
597       bbtkError("No package of the factory contains any black box <"
598                  <<name<<">");
599       }
600   }  
601   //===================================================================
602
603
604   //=================================================================== 
605   /// Inserts a package in the factory
606   void Factory::InsertPackage( Package* p )
607   {
608     bbtkDebugMessageInc("Core",9,"Factory::InsertPackage(\""<<
609                         p->GetName()<<"\")"<<std::endl);
610
611     PackageInfoType pack;
612     pack.mDynamicLibraryHandler = 0;
613     
614     pack.mPackage = p;
615
616     mPackageMap[p->GetName()] = pack;
617     bbtkDebugDecTab("Core",9);
618   }
619   //===================================================================
620   
621   //=================================================================== 
622   /// Removes a package from the factory (and deletes it)
623   void Factory::RemovePackage( Package* p )
624   {
625     bbtkDebugMessageInc("Core",9,"Factory::RemovePackage(\""<<
626                         p->GetName()<<"\")"<<std::endl);
627
628     PackageMapType::iterator i;
629     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
630       {
631          if (i->second.mPackage == p) break;
632       };
633     
634     if (i!=mPackageMap.end())
635       {
636       ClosePackage(i);
637       }
638     else 
639       {
640       bbtkError("Factory::RemovePackage(\""<<
641                  p->GetName()<<"\") : package absent from factory");
642       }
643
644     bbtkDebugDecTab("Core",9);
645   }
646   //===================================================================
647   
648
649   //===================================================================
650   /// Creates an instance of a black box of type <type> with name <name>
651   BlackBox* Factory::NewBlackBox(const std::string& type, 
652                                  const std::string& name) const
653   {
654     bbtkDebugMessageInc("Core",7,"Factory::NewBlackBox(\""
655                         <<type<<"\",\""<<name<<"\")"<<std::endl);
656
657     BlackBox* b = 0; 
658     PackageMapType::const_iterator i;
659     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
660       {
661       b = i->second.mPackage->NewBlackBox(type,name);
662       if (b) break; 
663       }
664     if (!b) 
665       {
666        bbtkError("black box type \""<<type<<"\" unknown");
667       } 
668
669     bbtkDebugDecTab("Core",7);
670     return b;
671   }
672   //===================================================================
673
674   //===================================================================
675   /// Creates an instance of a black box of type <type> with name <name>
676   BlackBox* Factory::NewAdaptor(TypeInfo typein,
677                      TypeInfo typeout,
678                      const std::string& name) const
679   {
680     bbtkDebugMessageInc("Core",8,"Factory::NewAdaptor(<"
681                         <<TypeName(typein)<<">,<"
682                         <<TypeName(typeout)<<">,\""
683                         <<name<<"\")"<<bbtkendl);
684
685
686     BlackBox* b = 0; 
687     PackageMapType::const_iterator i;
688     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
689       {
690       b = i->second.mPackage->NewAdaptor(typein,typeout,name);
691       if (b) break; 
692       }
693     if (!b) 
694       {
695       bbtkError("no <"
696           <<TypeName(typein)<<"> to <"
697           <<TypeName(typeout)
698           <<"> adaptor available");
699       } 
700     
701     bbtkDebugDecTab("Core",7);
702     return b; 
703   }
704   //===================================================================
705
706   //===================================================================
707   /// Creates an instance of a connection
708   Connection* Factory::NewConnection(BlackBox* from,
709                                      const std::string& output,
710                                      BlackBox* to,
711                                      const std::string& input) const
712   {
713     bbtkDebugMessage("Core",7,"Factory::NewConnection(\""
714                       <<from->bbGetName()<<"\",\""<<output<<"\",\""
715                       <<to->bbGetName()<<"\",\""<<input
716                       <<"\")"<<std::endl);
717     
718     return new Connection(from,output,to,input);
719     /*  
720        Connection* c;
721     // !!! WARNING : WE NEED TO TEST THE TYPE NAME EQUALITY 
722     // BECAUSE IN DIFFERENT DYN LIBS THE type_info EQUALITY CAN 
723     // BE FALSE (DIFFERENT INSTANCES !)
724   
725     std::string t1 ( from->bbGetOutputType(output).name() );
726     std::string t2 ( to->bbGetInputType(input).name() );
727
728
729     if ( t1 == t2 ) 
730        //from->bbGetOutputType(output) ==
731        // to->bbGetInputType(input) )
732       {
733          c = new Connection(from,output,to,input);
734       }
735     else 
736       {
737          //   std::cout << "Adaptive connection "<<std::endl;
738          std::string name;
739          name = from->bbGetName() + "." + output + "-" 
740                                   + to->bbGetName() + "." + input; 
741
742          BlackBox* b = 0; 
743          PackageMapType::const_iterator i;
744          for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
745          {
746              b = i->second.mPackage->NewAdaptor(from->bbGetOutputType(output),
747                                                   to->bbGetInputType(input),
748                                                   name);
749              if (b) break; 
750          } 
751          if (!b)  
752          {  
753             bbtkError("did not find any <"
754                        <<TypeName(from->bbGetOutputType(output))
755                        <<"> to <"
756                        <<TypeName(to->bbGetInputType(input))
757                        <<"> adaptor");
758          } 
759          c = new AdaptiveConnection(from,output,to,input,b);
760       }
761       bbtkDebugDecTab("Core",7);
762     
763       return c;
764     */
765   }
766   //===================================================================
767
768
769
770   //===================================================================
771   const Package* Factory::GetPackage(const std::string& name) const
772   {
773     bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
774                          <<std::endl);
775
776     PackageMapType::const_iterator i = mPackageMap.find(name);
777     if ( i != mPackageMap.end() ) 
778     {
779       bbtkDebugDecTab("Core",9); 
780       return i->second.mPackage;
781     }
782     else 
783     {
784        bbtkDebugDecTab("Core",9);
785        bbtkError("package \""<<name<<"\" unknown");
786     }
787     
788     bbtkDebugDecTab("Core",9);  
789   }
790   //===================================================================
791   
792   //===================================================================
793   Package* Factory::GetPackage(const std::string& name) 
794   {
795     bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
796                          <<std::endl);
797
798     PackageMapType::const_iterator i = mPackageMap.find(name);
799     if ( i != mPackageMap.end() ) 
800     {
801       bbtkDebugDecTab("Core",9); 
802       return i->second.mPackage;
803     }
804     else 
805     {
806        bbtkDebugDecTab("Core",9);
807        bbtkError("package \""<<name<<"\" unknown");
808     }
809     
810     bbtkDebugDecTab("Core",9);  
811   }
812   //===================================================================
813
814   //===================================================================
815   void Factory::WriteDotFilePackagesList(FILE *ff)
816   {
817     bbtkDebugMessageInc("Core",9,"Factory::WriteDotFilePackagesList()"
818                          <<std::endl);
819
820     fprintf( ff , "\n");
821     fprintf( ff , "subgraph cluster_FACTORY {\n");
822     fprintf( ff , "  label = \"PACKAGES\"%s\n",  ";");
823     fprintf( ff , "  style=filled%s\n",";");
824     fprintf( ff , "  color=lightgrey%s\n",";");
825     fprintf( ff , "  rankdir=TB%s\n",";");
826
827     std::string url;
828     PackageMapType::const_iterator i;
829     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
830     {
831        url=GetPackage(i->first)->GetDocURL();
832        fprintf(ff,"  %s [shape=ellipse, URL=\"%s\"]%s\n",i->first.c_str(),url.c_str(),";" );
833     }
834     fprintf( ff , "}\n\n");
835     bbtkDebugDecTab("Core",9);
836   }
837   //===================================================================
838
839
840  void Factory::ShowGraphTypes(const std::string& name) const
841  {
842    bool found = false;
843    PackageMapType::const_iterator i;
844    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
845    {
846       if (i->second.mPackage->ContainsBlackBox(name)) 
847       {
848          std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
849
850             // Don't pollute the file store with  "doc_tmp" directories ...    
851          std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
852          std::string directory = "\"" + default_doc_dir + separator + "doc_tmp"  +separator + "\"";
853          std::string filename2 =  default_doc_dir + separator + "doc_tmp" + separator + "tmp.html"; 
854
855 #if defined(_WIN32)  
856         std::string command("start \"Titre\" /D ");
857 #else 
858         std::string command("gnome-open ");
859 #endif
860         command=command + directory +" tmp.html";
861         FILE *ff;
862         ff=fopen(filename2.c_str(),"w");
863
864         fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
865         fprintf(ff,"  window.location=\"%s#%s\";\n" , i->second.mPackage->GetDocURL().c_str(),name.c_str() );
866         fprintf(ff,"//--></script></head><body></body></html>\n");
867
868
869         //fprintf(ff, "<a  href=\"%s#%s\">Link</a>\n", i->second.mPackage->GetDocURL().c_str(),name.c_str() );
870         fclose(ff);
871         system( command.c_str() );      
872         found = true;
873      }
874    }
875     
876    bbtkDebugDecTab("Core",9);
877    if (!found) 
878    {
879       bbtkError("No package of the factory contains any black box <"
880                 <<name<<">");
881    }
882  }
883
884 }
885