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