]> 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/04/22 06:59:31 $
8 Version:   $Revision: 1.35 $
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 #include <cctype>    // std::toupper
39
40
41 namespace bbtk
42 {
43
44   //===================================================================
45   /// Default ctor
46   Factory::Pointer Factory::New()
47   {
48     bbtkDebugMessage("Kernel",9,"Factory::New()"<<std::endl);
49     return MakePointer(new Factory());
50   }
51   //===================================================================
52
53   //===================================================================
54   /// Default ctor
55   Factory::Factory()
56     : mExecuter()
57   {
58     bbtkDebugMessage("Kernel",7,"Factory::Factory()"<<std::endl);
59   }
60   //===================================================================
61
62   //===================================================================
63   /// Dtor
64   Factory::~Factory()
65   {
66     bbtkDebugMessageInc("Kernel",7,"Factory::~Factory()"<<std::endl);
67     CloseAllPackages();
68     bbtkDebugDecTab("Kernel",7);
69   }
70   //===================================================================
71
72
73
74   //===================================================================
75   void Factory::Reset()
76   {
77     bbtkDebugMessageInc("Kernel",7,"Factory::Reset()"<<std::endl);
78     CloseAllPackages();
79     bbtkDebugDecTab("Kernel",7);
80   }
81   //===================================================================
82
83
84   // ===================================================================
85   bool Factory::DoLoadPackage(std::string libname,
86                               std::string pkgname,
87                               std::string path)
88   {
89     
90     Package::Pointer p = Package::CreateFromDynamicLibrary(libname,
91                                                            pkgname,
92                                                            path);
93     if (p!=0)
94       {
95         //===================================================================
96         bbtkMessage("Output",2,p->GetName()<<" "
97                     <<p->GetVersion()
98                     <<" "
99                     <<p->GetAuthor() << " Category(s) :"
100                     <<p->GetCategory()
101                     <<std::endl);
102         bbtkMessage("Output",2,p->GetDescription()<<std::endl);
103         //===================================================================
104         p->AddFactory(GetThisPointer<Factory>());
105         mPackageMap[pkgname] = p;
106         return true;
107       }
108     return false;
109     
110   }
111   
112   //===================================================================
113   /// \brief Loads a package.
114   ///
115   /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
116   /// Tries to open the dynamic library :
117   /// - "libbb<name>.so" for linux systems,
118   /// - "bb<name>.dll" for windows systems.
119   /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
120   /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
121   /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
122   
123   /// now, filename is only the last name (no longer the full name!)
124   /// it will be searched within *all* the paths given in bbtk_config.xml
125   
126
127   
128   void Factory::LoadPackage( const std::string& name )
129   {
130   // Note : in the following :
131   // name : the user supplied name
132   //      - abreviated name    e.g.       pkg   pkg.so   libbpkg   libbbpkg.so
133   //      - relative full name e.g.       ./libbbpkg.so   ../../libbbpkg.so
134   //      - absolute full name e.g.       /home/usrname/proj/lib/libbbpkg.so
135   //          same for Windows, with      c:, d: ...
136   //
137   // lastname : string before the last / (if any), or user supplied name
138
139     bbtkDebugMessageInc("Kernel",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
140     bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
141
142     std::vector<std::string> package_paths;
143     std::string libname;  // full path library name
144     std::string pkgname;  // e.g. libbb<pkgname>.so
145
146     std::string upath;
147     pkgname = Utilities::ExtractPackageName(name,upath);
148
149     bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
150     bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
151
152     // no loading package if already loaded
153     PackageMapType::iterator iUnload;
154     iUnload = mPackageMap.find(pkgname);
155     if (iUnload != mPackageMap.end())
156     {
157       bbtkMessage("Output",2,"["<< pkgname <<"] already loaded" << std::endl);
158       return;
159     }
160
161 // =================================================
162 // The following structure was checked to work
163 // with any type of relative/absolute path.
164 // Please don't modify it without checking
165 // *all* the cases. JP
166 //==================================================
167
168 //std::cout << "upath [" << upath << "]" << std::endl;
169
170     bool ok = false;
171     bool foundFile = false;
172
173     // If path provided by user will be the first scanned :
174     // push it into vector of paths
175     if (upath.length()>0)   // ------------------------------------- check user supplied location
176     {
177        if (name[0] != '.' && name[0] != '/' && name[1]!= ':')
178        {
179           bbtkError("Use absolute or relative path name! ["<<name<<"] is an illegal name");
180           return;
181        }
182
183       // std::string path = Utilities::ExpandLibName(upath, false);
184        std::string path = Utilities::ExpandLibName(name,false); // keep last item, here.
185          
186        if (path != "")
187        {
188           std::string p2;
189           Utilities::ExtractPackageName(path,p2);
190           //libname = Utilities::MakeLibnameFromPath(path, pkgname);
191           libname = Utilities::MakeLibnameFromPath(p2, pkgname); // remove last item
192           // Check if library exists
193           if ( !Utilities::FileExists(libname) )
194           {
195           // The following is *NOT* a debug time message :
196           // It's a user intended message.
197           // Please don't remove it.
198             bbtkMessage("Output",3,"   [" <<libname 
199                         <<"] : doesn't exist" <<std::endl);
200           }
201           else
202           {
203              ok = DoLoadPackage( libname, pkgname, path);         
204           }
205        }
206        else
207        {
208           bbtkError("Path ["<<upath<<"] doesn't exist");
209           return;
210        }
211     }
212     else     // ----------------------------------------------------- iterate on the paths  
213     {
214
215     std::string path;
216     package_paths = ConfigurationFile::GetInstance().Get_package_paths();
217     std::vector<std::string>::iterator i;
218     for (i=package_paths.begin();i!=package_paths.end();++i)
219     {
220         foundFile = false;
221         path = *i;
222
223         // we *really* want '.' to be the current working directory
224         if (path == ".")
225         {
226           char buf[2048]; // for getcwd
227           char * currentDir = getcwd(buf, 2048);
228           std::string cwd(currentDir);
229           path = currentDir;
230         }
231
232         libname = Utilities::MakeLibnameFromPath(path, pkgname);
233
234         bbtkMessage("Debug",2,"-> Trying to load [" << libname << "]" <<std::endl);
235
236       // Check if library exists           
237         if ( !Utilities::FileExists(libname) )
238         {
239         // The following is *NOT* a debug time message :
240         // It's a user intended message.
241         // Please don't remove it.
242           bbtkMessage("Output",3,
243                       "   [" <<libname <<"] : doesn't exist" <<std::endl);
244            continue;  // try next path
245         }
246         foundFile = true; 
247
248       // Try to Load the library
249
250         ok = DoLoadPackage( libname, pkgname, path);
251         if (ok)
252         {
253            bbtkMessage("Debug",2,"   OK"<<std::endl);
254            break; // a package was found; we stop iterating
255         }
256     } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
257
258 }
259
260     if( !ok )  // nothing was loaded
261     {
262       if (!foundFile)
263       {
264         bbtkError("Could not find package ["<<pkgname<< "]");
265       }
266       else
267       {
268 #if defined(__GNUC__)
269         bbtkError("Could not load package ["<< pkgname
270                   <<"] :" << std::endl << "   " << dlerror());
271 #elif defined(_WIN32)
272         bbtkError("Could not load package ["<<pkgname
273                  <<"] : " << std::endl << "   " <<libname<<" not found");
274
275     // look how to get the error message on win
276     //<<dlerror());
277     // it is the bordel !! (the bloody fucking bordel, you mean?)
278     // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
279 #endif
280       }
281     }
282     bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
283
284   }
285
286   //===================================================================
287   /// \brief UnLoads a package.
288   ///
289   /// The package must have been previously loaded by LoadPackage.
290   /// If the entry is found in the map, calls ClosePackage
291  void Factory::UnLoadPackage( const std::string& name )
292  {
293     bbtkDebugMessageInc("Kernel",7,"Factory::UnLoadPackage(\""
294                        <<name<<"\")"<<std::endl);
295   
296     PackageMapType::iterator i;
297     i = mPackageMap.find(name);
298     if (i == mPackageMap.end()) 
299     {
300       bbtkError("cannot unload package \""<<name
301                 <<"\" : package not loaded !");
302     }
303     ClosePackage(i);
304     bbtkDebugDecTab("Kernel",7);
305   }
306   //===================================================================
307
308
309   //===================================================================
310   void Factory::CloseAllPackages()
311   {
312     bbtkDebugMessageInc("Kernel",7,"Factory::CloseAllPackages()"<<std::endl);
313     while (mPackageMap.begin() != mPackageMap.end())
314       {
315         PackageMapType::iterator i = mPackageMap.begin();
316         ClosePackage(i);
317       }
318     bbtkDebugDecTab("Kernel",7);
319   }
320   //===================================================================
321
322   //===================================================================
323   /// \brief Close the package referenced by the iterator 
324  ///
325  /// First removes the factory from the set of factories which use the package
326  /// If the set is empty then :
327  /// If it is a dynamically loaded package :
328  /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
329  /// - Closes the dynamic library
330  /// Else :
331  /// - deletes the package normally
332  /// 
333  /// Finally erases the package entry in the packages map
334  void Factory::ClosePackage(PackageMapType::iterator& i) 
335   {   
336      bbtkDebugMessageInc("Kernel",7,"Factory::ClosePackage(\""
337                          <<i->second->GetName()
338                         <<"\")"<<std::endl);
339
340      
341      // Removes this from the set of factories which use the package
342      i->second->RemoveFactory(GetThisPointer<Factory>());
343      Package::WeakPointer p = i->second;
344      // remove the entry in the map
345      mPackageMap.erase(i);
346      // Release the package if not already destroyed
347      if (p.lock()) Package::Release(p);
348
349
350      bbtkDebugDecTab("Kernel",7);
351   }
352   //===================================================================
353   
354
355
356   //===================================================================  
357   /// Displays the list of packages loaded
358   void Factory::PrintPackages(bool details, bool adaptors) const
359   {
360     bbtkDebugMessageInc("Kernel",9,"Factory::PrintPackages"<<std::endl);
361
362     PackageMapType::const_iterator i;
363     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
364     {
365       bbtkMessage("Help",1, i->first << std::endl);
366       if (details) {
367          i->second->PrintBlackBoxes(false,adaptors);
368       }
369     }
370
371     bbtkDebugDecTab("Kernel",9);
372   }
373   //===================================================================
374
375   //===================================================================  
376   /// Displays help on a package
377   void Factory::HelpPackage(const std::string& name, bool adaptors) const
378   {
379     bbtkDebugMessageInc("Kernel",9,"Factory::HelpPackage(\""<<name<<"\")"
380                         <<std::endl);
381
382     PackageMapType::const_iterator i = mPackageMap.find(name);
383     if ( i != mPackageMap.end() ) 
384       {
385       bbtkMessage("Help",1, "Package "<<i->first<<" ");
386       
387       if (i->second->GetVersion().length()>0)
388         bbtkMessageCont("Help",1,"v" <<i->second->GetVersion());
389         
390       if (i->second->GetAuthor().length()>0)
391         bbtkMessageCont("Help",1,"- "<<i->second->GetAuthor());
392         
393       if (i->second->GetCategory().length()>0)
394         bbtkMessageCont("Help",1,"- "<<i->second->GetCategory());        
395         
396       bbtkMessageCont("Help",1,std::endl);
397       bbtkIncTab("Help",1);
398       bbtkMessage("Help",1,i->second->GetDescription()<<std::endl);
399       if (i->second->GetNumberOfBlackBoxes()>0) 
400         {
401           bbtkMessage("Help",1, "Black boxes : "<<std::endl);
402           i->second->PrintBlackBoxes(true,adaptors);
403         }
404       else 
405         {
406           bbtkMessage("Help",1, "No black boxes"<<std::endl);
407         }
408       bbtkDecTab("Help",1);
409       }
410     else 
411       {
412       bbtkDebugDecTab("Kernel",9);
413       bbtkError("package \""<<name<<"\" unknown");
414       }
415     
416     bbtkDebugDecTab("Kernel",9);
417   }
418   //===================================================================
419
420   //===================================================================
421   /// Prints help on the black box of type <name>
422   /// Returns the package to which it belongs
423   void Factory::HelpBlackBox(const std::string& name, 
424                              std::string& package,
425                              bool full) const
426   {
427     bbtkDebugMessageInc("Kernel",9,"Factory::HelpBlackBox(\""<<name<<"\")"
428                         <<std::endl);
429
430     bool found = false;
431     PackageMapType::const_iterator i;
432     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
433       {
434       if (i->second->ContainsBlackBox(name)) 
435         {
436           i->second->HelpBlackBox(name,full);
437               package = i->second->GetName();
438           found = true;
439         }
440       }
441     
442     bbtkDebugDecTab("Kernel",9);
443     if (!found) 
444       {
445       bbtkError("No package of the factory contains any black box <"
446                  <<name<<">");
447       }
448   }  
449   //===================================================================
450
451
452   //=================================================================== 
453   /// Inserts a package in the factory
454   void Factory::InsertPackage( Package::Pointer p )
455   {
456     bbtkDebugMessageInc("Kernel",9,"Factory::InsertPackage(\""<<
457                         p->GetName()<<"\")"<<std::endl);
458
459     p->AddFactory(GetThisPointer<Factory>());
460     mPackageMap[p->GetName()] = p;
461
462     bbtkDebugDecTab("Kernel",9);
463   }
464   //===================================================================
465   
466   //=================================================================== 
467   /// Removes a package from the factory (and deletes it)
468   void Factory::RemovePackage( Package::Pointer p )
469   {
470     bbtkDebugMessageInc("Kernel",9,"Factory::RemovePackage(\""<<
471                         p->GetName()<<"\")"<<std::endl);
472
473     PackageMapType::iterator i;
474     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
475       {
476          if (i->second == p) break;
477       };
478     
479     if (i!=mPackageMap.end())
480       {
481         ClosePackage(i);
482       }
483     else 
484       {
485         bbtkError("Factory::RemovePackage(\""<<
486                   p->GetName()<<"\") : package absent from factory");
487       }
488
489     bbtkDebugDecTab("Kernel",9);
490   }
491   //===================================================================
492   
493
494   //===================================================================
495   /// Creates an instance of a black box of type <type> with name <name>
496   BlackBox::Pointer Factory::NewBlackBox(const std::string& type, 
497                                  const std::string& name) const
498   {
499     bbtkDebugMessageInc("Kernel",7,"Factory::NewBlackBox(\""
500                         <<type<<"\",\""<<name<<"\")"<<std::endl);
501
502     BlackBox::Pointer b; 
503     PackageMapType::const_iterator i;
504     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
505       {
506       b = i->second->NewBlackBox(type,name);
507       if (b) break; 
508       }
509     if (!b) 
510       {
511        bbtkError("black box type \""<<type<<"\" unknown");
512       } 
513
514     bbtkDebugDecTab("Kernel",7);
515     return b;
516   }
517   //===================================================================
518
519   //===================================================================
520   /// Creates an instance of a black box of type <type> with name <name>
521   BlackBox::Pointer Factory::NewAdaptor(const DataInfo& typein,
522                                 const DataInfo& typeout,
523                                 const std::string& name) const
524   {
525     bbtkDebugMessageInc("Kernel",8,"Factory::NewAdaptor("
526                         <<typein<<","
527                         <<typeout<<",\""
528                         <<name<<"\")"<<bbtkendl);
529
530
531     BlackBox::Pointer b; 
532     PackageMapType::const_iterator i;
533     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
534       {
535       b = i->second->NewAdaptor(typein,typeout,name);
536       if (b) break; 
537       }
538     if (!b) 
539       {
540         bbtkError("no "<<typein<<" to "<<typeout
541                   <<" adaptor available");
542       } 
543     
544     bbtkDebugDecTab("Kernel",7);
545     return b; 
546   }
547   //===================================================================
548
549
550   //===================================================================
551   /// Creates an instance of a black box of type <type> with name <name>
552   BlackBox::Pointer Factory::NewWidgetAdaptor(const DataInfo& typein,
553                                       const DataInfo& typeout,
554                                       const std::string& name) const
555   {
556     bbtkDebugMessageInc("Kernel",8,"Factory::NewWidgetAdaptor(<"
557                         <<typein<<">,<"
558                         <<typeout<<">,\""
559                         <<name<<"\")"<<bbtkendl);
560
561
562     BlackBox::Pointer b; 
563     PackageMapType::const_iterator i;
564     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
565       {
566         b = i->second->NewWidgetAdaptor(typein,
567                                                  typeout,
568                                                  name);
569       if (b) break; 
570       }
571     if (!b) 
572       {
573         bbtkError("no "<<typein<<" to "<<typeout
574                   <<"> widget adaptor available");
575       } 
576     
577     bbtkDebugDecTab("Kernel",7);
578     return b; 
579   }
580   //===================================================================
581
582   //===================================================================
583   /// Creates an instance of a black box of type <type> with name <name>
584   bool Factory::FindAdaptor(const DataInfo& typein,
585                                   const DataInfo& typeout,
586                                   std::string& adaptor) const
587   {
588     bbtkDebugMessageInc("Kernel",8,"Factory::FindAdaptor(<"
589                         <<typein<<">,<"
590                         <<typeout<<">)"<<bbtkendl);
591     
592     bool b = false;
593     PackageMapType::const_iterator i;
594     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
595       {
596         b = i->second->FindAdaptor(typein,
597                                             typeout,
598                                             adaptor);
599         if (b) break; 
600       }
601     /*
602     if (!b) 
603       {
604         bbtkError("no "<<typein<<" to "<<typeout
605                   <<"> widget adaptor available");
606       } 
607     */
608
609     bbtkDebugDecTab("Kernel",7);
610     return b; 
611   }
612   //===================================================================
613
614   //===================================================================
615   /// Creates an instance of a black box of type <type> with name <name>
616   bool Factory::FindWidgetAdaptor(const DataInfo& typein,
617                                   const DataInfo& typeout,
618                                   std::string& adaptor) const
619   {
620     bbtkDebugMessageInc("Kernel",8,"Factory::FindWidgetAdaptor(<"
621                         <<typein<<">,<"
622                         <<typeout<<">)"<<bbtkendl);
623     
624     bool b = false;
625     PackageMapType::const_iterator i;
626     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
627       {
628         b = i->second->FindWidgetAdaptor(typein,
629                                                   typeout,
630                                                   adaptor);
631         if (b) break; 
632       }
633     bbtkDebugDecTab("Kernel",7);
634     return b; 
635   }
636   //===================================================================
637
638   //===================================================================
639   /// Creates an instance of a black box of type <type> with name <name>
640   bool Factory::FindWidgetAdaptor2(const DataInfo& typein,
641                                   const DataInfo& typeout,
642                                   std::string& widget,
643                                   std::string& adaptor) const
644   {
645     bbtkDebugMessageInc("Kernel",8,"Factory::FindWidgetAdaptor(<"
646                         <<typein<<">,<"
647                         <<typeout<<">)"<<bbtkendl);
648     
649     bool b = false;
650     adaptor = widget = "";
651     PackageMapType::const_iterator i;
652     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
653       {
654         b = i->second->FindWidgetAdaptor(typein,
655                                                   typeout,
656                                                   widget);
657         if (b) break; 
658       }
659     if (!b) 
660       {
661         // Look for a widget adaptor with good nature out
662         bbtkMessage("Kernel",5,
663                     "*** Looking for a two pieces widget adaptor for : "
664                     << typein << "->"<<typeout<<std::endl);
665         for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
666           {
667             Package::AdaptorMapType::const_iterator j;
668             for (j=i->second->GetAdaptorMap().begin();
669                  j!=i->second->GetAdaptorMap().end();
670                  ++j)
671               {
672                 if ( ( j->first.mKind ==  
673                        BlackBoxDescriptor::DEFAULT_GUI) &&
674                      //(j->first.mTypeIn == typein) &&
675                      (j->first.mTypeOut.GetNature() == typeout.GetNature() ) 
676                      )
677                   {
678                     widget = j->second.lock()->GetTypeName();
679                     bbtkMessage("Kernel",5,
680                                 "===> Found first part : "<<widget
681                                 << " "<<j->first.mTypeIn<<"->"
682                                 <<j->first.mTypeOut<<std::endl);
683                     DataInfo ti( j->first.mTypeOut.GetType(), "");
684                     DataInfo to( typeout.GetType(), "");
685                     b = FindAdaptor( ti, to, adaptor );
686                     if (b) 
687                       {
688                         bbtkMessage("Kernel",5,
689                                     "===> Found second part : "<<adaptor
690                                     <<std::endl);
691                         break;
692                       }
693                     else
694                       {
695                         bbtkMessage("Kernel",5,
696                                     "===> No second part found"<<std::endl);
697                       }
698                   }
699               }
700             if (b) break;
701           }
702       }
703     bbtkDebugDecTab("Kernel",7);
704     return b; 
705   }
706   //===================================================================
707
708   //===================================================================
709   /// Creates an instance of a connection
710   Connection::Pointer Factory::NewConnection(BlackBox::Pointer from,
711                                              const std::string& output,
712                                              BlackBox::Pointer to,
713                                              const std::string& input) const
714   {
715     bbtkDebugMessage("Kernel",7,"Factory::NewConnection(\""
716                       <<from->bbGetName()<<"\",\""<<output<<"\",\""
717                       <<to->bbGetName()<<"\",\""<<input
718                       <<"\")"<<std::endl);
719     
720     return Connection::New(from,output,to,input,
721                            GetThisPointer<Factory>());
722   }
723   //===================================================================
724
725
726
727   //===================================================================
728   Package::Pointer Factory::GetPackage(const std::string& name) const
729   {
730     bbtkDebugMessageInc("Kernel",9,"Factory::GetPackage(\""<<name<<"\")"
731                          <<std::endl);
732
733     PackageMapType::const_iterator i = mPackageMap.find(name);
734     if ( i != mPackageMap.end() ) 
735     {
736       bbtkDebugDecTab("Kernel",9); 
737       return i->second;
738     }
739     else 
740     {
741        bbtkDebugDecTab("Kernel",9);
742        bbtkError("package \""<<name<<"\" unknown");
743     }
744     
745     bbtkDebugDecTab("Kernel",9);  
746   }
747   //===================================================================
748   
749
750   //===================================================================
751   void Factory::CheckPackages() const
752   {
753     bbtkMessage("Debug",1,"****** Checking Factory "<<(void*)this
754                  <<std::endl);
755     PackageMapType::const_iterator i;
756     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
757       {
758         i->second->CheckBoxes();
759       }
760     bbtkMessage("Debug",1,"****** Checking Factory "<<(void*)this
761                 <<" ... OK"<<std::endl);
762   }
763   //===================================================================
764
765   //===================================================================
766   void Factory::WriteDotFilePackagesList(FILE *ff)
767   {
768
769     bbtkDebugMessageInc("Kernel",9,"Factory::WriteDotFilePackagesList()"
770                          <<std::endl);
771
772     fprintf( ff , "\n");
773     fprintf( ff , "subgraph cluster_FACTORY {\n");
774     fprintf( ff , "  label = \"PACKAGES\"%s\n",  ";");
775     fprintf( ff , "  style=filled%s\n",";");
776     fprintf( ff , "  color=lightgrey%s\n",";");
777     fprintf( ff , "  rankdir=TB%s\n",";");
778
779     std::string url;
780     PackageMapType::const_iterator i;
781     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
782     {
783        url=GetPackage(i->first)->GetDocURL();
784        fprintf(ff,"  %s [shape=ellipse, URL=\"%s\"]%s\n",i->first.c_str(),url.c_str(),";" );
785     }
786     fprintf( ff , "}\n\n");
787     bbtkDebugDecTab("Kernel",9);
788   }
789   //===================================================================
790
791
792  void Factory::ShowGraphTypes(const std::string& name) const
793  {
794
795    bool found = false;
796    PackageMapType::const_iterator i;
797    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
798    {
799       if (i->second->ContainsBlackBox(name)) 
800       {
801          std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
802
803             // Don't pollute the file store with  "temp_dir" directories ...    
804          std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
805          std::string directory = "\"" + default_doc_dir + separator + "temp_dir"  +separator + "\"";
806          std::string filename2 =  default_doc_dir + separator + "temp_dir" + separator + "tmp.html"; 
807
808 #if defined(_WIN32)  
809         std::string command("start \"Titre\" /D ");
810 #else 
811         std::string command("gnome-open ");
812 #endif
813         command=command + directory +" tmp.html";
814         FILE *ff;
815         ff=fopen(filename2.c_str(),"w");
816
817         fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
818         fprintf(ff,"  window.location=\"%s#%s\";\n" , i->second->GetDocURL().c_str(),name.c_str() );
819         fprintf(ff,"//--></script></head><body></body></html>\n");
820
821
822         //fprintf(ff, "<a  href=\"%s#%s\">Link</a>\n", i->second->GetDocURL().c_str(),name.c_str() );
823         fclose(ff);
824         system( command.c_str() );      
825         found = true;
826      }
827    }
828     
829    bbtkDebugDecTab("Kernel",9);
830    if (!found) 
831    {
832       bbtkError("No package of the factory contains any black box <"
833                 <<name<<">");
834    }
835  }
836     
837
838
839
840   void Factory::CreateHtmlIndex(IndexEntryType type, 
841                                 const std::string& filename)
842   {
843     bbtkDebugMessageInc("Kernel",9,"Factory::CreateHtmlIndex(\""
844                         <<filename<<"\")"<<bbtkendl);
845     
846     std::string title;
847
848     typedef std::map<std::string, 
849       std::vector<BlackBoxDescriptor::Pointer> > IndexType;
850     IndexType index;
851     // Builds the index map
852     PackageMapType::const_iterator i;
853     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
854       {
855         Package::Pointer pack = i->second;
856         if (pack->GetName()=="user") continue;
857         Package::BlackBoxMapType::const_iterator j;
858         for (j = pack->GetBlackBoxMap().begin(); 
859              j!= pack->GetBlackBoxMap().end(); 
860              ++j)
861           {
862             
863             // Skip adaptors 
864             if ( type==Adaptors )
865               {  
866                 if (j->second->GetKind() == BlackBoxDescriptor::STANDARD )
867                   continue;
868               }
869             else 
870               if (j->second->GetKind() != BlackBoxDescriptor::STANDARD )
871                 continue;
872
873             std::vector<std::string> keys;
874             if (type==Packages)
875               {
876                 std::string k("");
877                 k += pack->GetName();
878                 keys.push_back(k);
879                 title = "Boxes by package";
880               }
881             else if ((type==Initials) || (type==Adaptors))
882               {
883                 std::string init(" ");
884                 init[0] =  std::toupper(j->second->GetTypeName()[0]);
885                 keys.push_back(init);
886                 title = "Alphabetical list";
887               }
888             else if (type==Categories)
889               {
890                 // Split the category string 
891                 std::string delimiters = ";,";
892                 Utilities::SplitString(j->second->GetCategory(),
893                                        delimiters,keys);
894                 if (keys.size()==0) 
895                   keys.push_back(" NONE");
896                 title = "Boxes by category";
897               }
898     
899             
900             std::vector<std::string>::const_iterator k;
901             for (k=keys.begin(); k!=keys.end(); ++k )
902               {
903                 IndexType::iterator p;
904                 p = index.find(*k);
905                 if (p != index.end()) 
906                   {
907                     p->second.push_back(j->second);
908                   }
909                 else 
910                   {
911                     std::vector<BlackBoxDescriptor::Pointer> v;
912                     v.push_back(j->second);
913                     index[*k] = v;
914                   }
915               }
916             
917           }
918       }   
919     // Creates the file 
920     //---------------------
921     // Open output file
922     std::ofstream s;
923     s.open(filename.c_str());
924     if (!s.good()) 
925     {
926        bbtkError("Factory::CreateHtmlIndex : could not open file '"
927                  <<filename<<"'");
928     }
929     
930     //----------------------
931     // Html head
932     s << "<html lang=\"en\">\n";
933     s << "<head>\n";
934     s << "<title>"<<title<<"</title>\n";
935     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
936     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
937     s << "<meta name=\"generator\" content=\"\">\n";
938     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
939     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
940     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
941     s << "pre.display { font-family:inherit }\n";
942     s << "pre.format  { font-family:inherit }\n";
943     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
944     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
945     s << "pre.smallexample { font-size:smaller }\n";
946     s << "pre.smalllisp    { font-size:smaller }\n";
947     s << "span.sc    { font-variant:small-caps }\n";
948     s << "span.roman { font-family:serif; font-weight:normal; } \n";
949     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
950     s << "--></style>\n";
951     s << "</head>\n";
952     //----------------------
953
954     //----------------------
955     // Html body
956     s << "<body>\n";
957     s << "<a name=\"Top\"></a>\n"; 
958     s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
959     s << "<p>\n";
960     IndexType::iterator ii;
961     for (ii=index.begin();ii!=index.end();++ii)
962       {
963         s << "<a href=\"#"<<ii->first<<"\">"<<ii->first<<"</a>&nbsp;&nbsp;";    
964       }
965
966     for (ii=index.begin();ii!=index.end();++ii)
967       {
968         s << "<p><hr>\n";
969         s << "<p><a href=\"#Top\">Top</a>";
970         if (type==Packages)
971           {
972             s << "<a name=\""<<ii->first<<"\"></a>\n"; 
973             s << "<p><a href=\""<<ii->first<<"/index.html\">"
974               << ii->first<<"</a>\n"; 
975
976             s << "&nbsp;&nbsp;-&nbsp;&nbsp;\n"; 
977
978             s << "<a name=\"doxygen\"></a>\n"; 
979             s << "<a href=..\\doxygen\\" << ii->first << "/main.html>(Doxygen documentation of the source)</a>\n"; 
980           }
981         else 
982           {
983             s << "<a name=\""<<ii->first<<"\"></a>\n"; 
984             s << "<p><b>"<<ii->first<<"</b>\n";
985           }
986         s << "<ul>\n";
987
988         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
989
990         std::vector<BlackBoxDescriptor::Pointer>::iterator di;
991         for (di=ii->second.begin();di!=ii->second.end();++di)
992           {
993             std::string pack = (*di)->GetPackage()->GetName();
994             std::string name = (*di)->GetTypeName();
995             Utilities::html_format(name);
996             std::string descr = (*di)->GetDescription();
997             Utilities::html_format(descr);
998             s << "<TR>";
999             s << "<TD style='vertical-align: top;'>";
1000             s << "&nbsp;&nbsp;&nbsp;<a href=\""<<pack
1001               <<"/index.html#"<<name<<"\">"
1002               <<pack<<"::"<<name<<"</a>";
1003             s << "</TD> ";
1004             s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1005             s << "</TR>\n";
1006           }    
1007         s << "</TABLE>\n";
1008         s << "</ul>\n";
1009         s << "</div>\n";
1010       }
1011     //----------------------
1012     // Footer 
1013     time_t rawtime;
1014     tm * ptm;
1015     time ( &rawtime );
1016     ptm = gmtime ( &rawtime );
1017
1018     s << "<p><hr>\n";
1019     s << "Automatically generated by <b>bbi</b> on "
1020       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
1021       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1022     s << "</body></html>\n"; 
1023     s.close();
1024     //----------------------
1025
1026     // End
1027     bbtkDebugDecTab("Kernel",9);
1028   }
1029
1030  //==========================================================================
1031   std::string Factory::GetObjectName() const
1032   {
1033     return std::string("Factory");
1034   }
1035   //==========================================================================
1036   
1037   //==========================================================================
1038   std::string  Factory::GetObjectInfo() const 
1039   {
1040     std::stringstream i;
1041     return i.str();
1042   }
1043   //==========================================================================
1044
1045   //==========================================================================
1046 size_t  Factory::GetObjectSize() const 
1047 {
1048   size_t s = Superclass::GetObjectSize();
1049   s += Factory::GetObjectInternalSize();
1050   return s;
1051   }
1052   //==========================================================================
1053   //==========================================================================
1054 size_t  Factory::GetObjectInternalSize() const 
1055 {
1056   size_t s = sizeof(Factory);
1057   return s;
1058   }
1059   //==========================================================================
1060   //==========================================================================
1061   size_t  Factory::GetObjectRecursiveSize() const 
1062   {
1063     size_t s = Superclass::GetObjectRecursiveSize();
1064     s += Factory::GetObjectInternalSize();
1065
1066     PackageMapType::const_iterator i;
1067     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
1068     {
1069       s += i->second->GetObjectRecursiveSize();
1070     }
1071     return s;
1072   }
1073   //==========================================================================
1074
1075 }
1076