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