]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
#3203 BBTK Feature New Normal vtk7itk4wx3-mingw64
[bbtk.git] / kernel / src / bbtkPackage.cxx
1 /*
2  # ---------------------------------------------------------------------
3  #
4  # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5  #                        pour la SantÈ)
6  # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7  # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8  # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9  #
10  #  This software is governed by the CeCILL-B license under French law and
11  #  abiding by the rules of distribution of free software. You can  use,
12  #  modify and/ or redistribute the software under the terms of the CeCILL-B
13  #  license as circulated by CEA, CNRS and INRIA at the following URL
14  #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15  #  or in the file LICENSE.txt.
16  #
17  #  As a counterpart to the access to the source code and  rights to copy,
18  #  modify and redistribute granted by the license, users are provided only
19  #  with a limited warranty  and the software's author,  the holder of the
20  #  economic rights,  and the successive licensors  have only  limited
21  #  liability.
22  #
23  #  The fact that you are presently reading this means that you have had
24  #  knowledge of the CeCILL-B license and that you accept its terms.
25  # ------------------------------------------------------------------------ */
26
27
28
29 /*=========================================================================                                                                               
30   Program:   bbtk
31   Module:    $RCSfile: bbtkPackage.cxx,v $
32   Language:  C++
33   Date:      $Date: 2012/11/16 08:49:01 $
34   Version:   $Revision: 1.37 $
35 =========================================================================*/
36
37
38
39 /**
40  *\file
41  *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
42  */
43 #include "bbtkPackage.h"
44 #include "bbtkComplexBlackBoxDescriptor.h"
45 #include "bbtkMessageManager.h"
46 #include "bbtkConfigurationFile.h"
47 #include <fstream>
48 #include <time.h>
49 #include "bbtkUtilities.h"
50
51 namespace bbtk
52 {
53   
54
55
56   //==========================================================================
57   /// Creates a new package
58   Package::Pointer Package::New(const std::string& name,
59                                 const std::string& author,
60                                 const std::string& description,
61                                 const std::string& version) 
62   {
63     bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
64                      <<bbtkendl);
65     Package::Pointer p = MakePointer(new Package(name,
66                                                author,
67                                                description,
68                                                version));
69     bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
70                      <<bbtkendl);
71     return p;
72   }
73   //==========================================================================
74
75   //==========================================================================
76   /// Ctor with the name of the package
77   Package::Package(const std::string& name,
78                    const std::string& author,
79                    const std::string& description,
80                    const std::string& version) 
81     :
82     mDynamicLibraryHandler(0),
83     mName(name),
84     mAuthor(author),
85     mDescription(description),
86     mVersion(version)
87   {
88 printf("EED Package::Package Start\n");
89     bbtkDebugMessage("object",2,"==> Package('"<<name<<"',...)"
90                      <<bbtkendl);
91
92     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
93 printf("EED Package::Package 1\n");
94     char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
95     std::string url = default_doc_dir; 
96     if (c != '/' && c !='\\') url = url + "/";
97     url = url +  "temp_dir/" + name + "/index.html";    
98 printf("EED Package::Package 2\n");
99     
100     SetDocURL(url);
101 printf("EED Package::Package 3\n");
102     SetDocRelativeURL("Relative url not set");
103 printf("EED Package::Package 4\n");
104
105     /*
106     std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
107     relurl += "/packages/"+name+"/bbdoc/index.html";
108     std::string url = ConfigurationFile::GetInstance().Get_url()
109       + relurl; 
110     SetDocURL(url);
111     SetDocRelativeURL(relurl);   
112     */
113
114     //    std::cout  << "   url=["<<url<<"]"<<std::endl;
115     //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
116     bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
117                      <<bbtkendl);
118 printf("EED Package::Package End\n");
119
120   }
121   //==========================================================================
122
123
124
125   //==========================================================================
126   /// Dtor
127   Package::~Package()
128   {
129     bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
130   }
131   //==========================================================================
132
133
134   //==========================================================================
135   void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
136                                                 const std::string& descname)
137   {
138     // Try to release descriptor
139     std::string packname = pack.lock()->GetName();
140     
141     bbtkDebugMessage("package",5,"--- Releasing descriptor '"
142                      <<packname<<"::"<<descname<<"'"<<bbtkendl);
143     
144     
145     Package::DescriptorMapType::iterator desc = 
146       pack.lock()->GetDescriptorMap().find(descname);
147     if (desc ==  pack.lock()->GetDescriptorMap().end())
148       {
149         bbtkDebugMessage("package",5,
150                          "    Descriptor has already been released"
151                         <<bbtkendl);
152         return;
153                   }
154     //    bbtkDebugMessage("package",3,
155     //               "    Trying unreferencing it ... "<<std::endl);
156     BlackBoxDescriptor::WeakPointer pdesc = desc->second;
157     desc->second.reset();
158     // if it is dead : remove it 
159     if (pdesc.expired()) 
160       {
161         bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
162         if (pack.expired()) 
163           {
164             bbtkDebugMessage("package",2,
165                              "     ... and caused its package death"
166                              <<bbtkendl);
167             return;
168           } // pack.expired
169         desc = pack.lock()->GetDescriptorMap().find(descname);
170         if (desc !=  pack.lock()->GetDescriptorMap().end())       pack.lock()->GetDescriptorMap().erase(desc);
171       }   else    {  //pdesc.expired
172       bbtkDebugMessage("package",5,"    ... Descriptor still alive ("
173                        <<pdesc.use_count()<<" refs)"
174                        <<bbtkendl);
175       pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
176     } // pdesc.expired
177   }
178   //==========================================================================
179
180
181   //==========================================================================
182   /// Release
183   void Package::Release(Package::WeakPointer pack)
184   {
185     std::string packname = pack.lock()->mName;
186     bbtkDebugMessage("package",1,"==> Package::Release('"<<
187                      packname<<"')"<<bbtkendl);
188
189     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
190     long ndesc = pack.lock()->GetDescriptorMap().size();
191     long nrefs = pack.use_count();
192
193     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
194                      <<ndesc<<" descr / dyn="
195                      <<dyn<<std::endl);
196
197     // A package is "free" from any external reference iff :
198     // i) It is not dynamically loaded and nrefs == ndesc 
199     // (each desc references its package) or
200     // ii) It is dynamically loaded and nrefs == ndesc + 1
201     // (A dynamic library holds a static pointer on the package it contains
202     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
203     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
204     if (nrefs == ndesc + dyn) 
205       {
206         bbtkDebugMessage("package",5,
207                          " -> No more external ref : checking descriptors"
208                          <<bbtkendl);
209         // We must take care that removing refs on descriptors 
210         // can lead to their deletion which can in turn unref 
211         // internal boxes which can release their descriptors hence 
212         // call Package::ReleaseBlackBoxDescriptor 
213         // As a consequence during descriptors release :
214         // 1) The map can change dynamically : we cannot iterate over it 
215         //    as any iterator can become invalid
216         // 2) The package can auto-destruct : we must test its existence 
217         //    after each release
218         // We must also take care of not locking the package pointer 
219         // or any ref count check in Package::ReleaseBlackBoxDescriptor
220         // would be wrong
221
222         // The list of descriptors names at start
223         std::vector<std::string> descnamelist;
224         DescriptorMapType::iterator i;
225         for (i=pack.lock()->mDescriptorMap.begin();
226              i!= pack.lock()->mDescriptorMap.end();
227              ++i)
228           descnamelist.push_back(i->first);
229
230         // Iterator over the initial names
231         std::vector<std::string>::iterator descname;
232         for (descname=descnamelist.begin();
233              descname!=descnamelist.end();
234              ++descname)
235           {
236             // Is package still alive ?
237             if (pack.expired()) 
238               {
239                 bbtkDebugMessage("package",1,"--- Package::Release('"<<
240                                  packname
241                                  <<"') : package expired during release : bailing out"<<bbtkendl);
242                 break;
243               }
244   
245 #if defined(MACOSX)
246                   BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
247                   if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
248                   {
249                           PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
250                   } 
251 #else
252                   PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
253 #endif
254
255           }
256
257         //
258         UnLoadDynamicLibrary(pack);
259         // Unload orphan dl packages 
260         Package::UnLoadReleasedDynamicallyLoadedPackages();
261
262       }
263     
264 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
265
266     bbtkDebugMessage("package",2,"<== Package::Release('"<<
267                      packname<<"')"<<bbtkendl);
268
269     if (!pack.expired())
270       {
271         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
272         long ndesc = pack.lock()->GetDescriptorMap().size();
273         long nrefs = pack.use_count();
274         
275         bbtkDebugMessage("package",1," ... Package still alive ("
276                          <<nrefs<<" refs / "
277                          <<ndesc<<" descr / dyn="
278                          <<dyn<<")"<<std::endl);
279       }
280     else 
281       {
282         bbtkDebugMessage("package",1," ... Package has been released"
283                          <<std::endl);
284       }
285 #endif
286   }
287   //==========================================================================
288
289   //==========================================================================
290   /// "Releases" the package
291   /// Signals the package that it can free the given descriptor
292   /// if they are no more used and free itself if it is no
293   /// more used
294   /// Note : Any non-weak pointer on the package must have been freed
295   void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
296                                           BlackBoxDescriptor::WeakPointer descr)
297   {
298     std::string packname = pack.lock()->mName;
299     std::string dname = descr.lock()->GetTypeName();    
300     bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
301                      packname<<"','"<<dname<<"') : refs="
302                      <<descr.use_count()<<bbtkendl);
303
304     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
305     long ndesc = pack.lock()->GetDescriptorMap().size();
306     long nrefs = pack.use_count();
307
308     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
309                      <<ndesc<<" descr / dynamically loaded = "
310                      <<dyn<<std::endl);
311
312     // A package is "free" from any external reference iff :
313     // i) It is not dynamically loaded and nrefs == ndesc 
314     // (each desc references its package) or
315     // ii) It is dynamically loaded and nrefs == ndesc + 1
316     // (A dynamic library holds a static pointer on the package it contains
317     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
318     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
319     if (nrefs == ndesc + dyn) 
320       {
321 #if defined(MACOSX)
322                   //
323                   if (dyn==0)
324                           PackageReleaseBlackBoxDescriptorInternal(pack,dname);
325 #else
326                   PackageReleaseBlackBoxDescriptorInternal(pack,dname);
327 #endif  
328       }
329     
330     // If the package is released and dynamically loaded 
331     // then put it in the static list mReleasedDynamicallyLoadedPackages
332     UnLoadDynamicLibrary(pack,false);
333         
334     bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
335                      packname<<"','"<<dname<<"'): refs="
336                      <<descr.use_count()<<bbtkendl);
337     /*
338     if (!pack.expired())
339       {
340         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
341         long ndesc = pack.lock()->GetDescriptorMap().size();
342         long nrefs = pack.use_count();
343         
344         bbtkDebugMessage("package",3," ... Package still alive ("
345                          <<nrefs<<" refs / "
346                          <<ndesc<<" descr / dyn="
347                          <<dyn<<")"<<std::endl);
348       }
349     else 
350       {
351         bbtkDebugMessage("package",3,"   ... Package has been released"
352                          <<std::endl);
353       }  
354     */
355   }
356   //==========================================================================    
357
358   //==========================================================================
359   /// Opens a dynamic library which contains a bbtk package
360   /// Returns the handler 
361   /// Load the package management symbols from the lib
362   /// returns false if a problem occured hence can be used 
363   /// to test that a dyn lib is a valid bbtk package lib
364   /// NB : The BBTK version exported from the library 
365   ///      is tested against the current bbtk version
366   DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
367                                                                                                          DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
368   {
369
370 printf("EED Package::OpenDynamicLibrary  %s   %s \n", libname.c_str(), package_name.c_str() );
371
372     bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
373                      <<libname<<")"<<std::endl);
374 #if defined(__GNUC__)
375
376     // Open shared lib
377     void *handler;
378     handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
379 //     handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
380           
381     if (!handler)
382       {
383         bbtkMessage("package",0,
384                     "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
385                     <<dlerror() << std::endl);
386         return 0;
387       }
388
389     bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
390
391     // Loads the Package bbtk version function 
392     std::string getvername(package_name);
393     getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
394     DLGetPackageBBTKVersionFunction getbbtkversion  = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
395     if (!getbbtkversion)
396       {
397         bbtkDebugMessage("package",3,"***"<<std::endl);
398         bbtkMessage("package",0,
399                     "BBTK ..ERROR.. loading shared library ["<<libname
400                     <<"] is not a valid bbtk package."
401                     <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
402         dlclose(handler);
403         return 0;
404       }
405
406     bbtkDebugMessage("package",3,"* Symbol ["<<getvername
407                      <<"] found"<<std::endl);
408     // version matches ?
409
410     if (getbbtkversion() != bbtk::GetVersion())
411       {
412         bbtkMessage("package",0,
413                     "BBTK ..ERROR.. loading: "<<package_name
414                         <<" - Shared library ["<<libname
415                     <<"] was build with bbtk version "
416                     <<getbbtkversion()
417                     <<" but the current program runs with version "
418                     <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
419         dlclose(handler);
420         return 0;
421         
422       }
423
424     bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
425             // Loads the Package get function
426     std::string getpackname(package_name);
427     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
428     getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
429     if (!getpack)
430       {
431         bbtkMessage("package",0,
432                     "BBTK ..ERROR.. loading shared library ["<<libname
433                     <<"] is not a valid bbtk package."
434                     <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
435         dlclose(handler);
436         return 0;
437       }
438   
439     bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
440     // Loads the Package delete function
441                                           
442     std::string delpackname(package_name);
443     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
444     delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
445     if (!delpack)
446       {
447         bbtkMessage("package",0,
448                     "BBTK ..ERROR.. loading shared library ["<<libname
449                     <<"] is not a valid bbtk package."
450                     <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
451         dlclose(handler);
452         return 0;
453       }
454     bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);                
455 #elif defined(_WIN32)
456     
457     HINSTANCE handler;
458     
459     SetErrorMode(0);
460     // Open shared lib
461     handler = LoadLibrary(libname.c_str());
462     if (!handler)
463       {
464         bbtkMessage("package",0,
465                     "BBTK ..ERROR..  could not open shared library [" <<libname<<"]"
466                     << std::endl);
467         DWORD dwErrorCode = 0;
468         dwErrorCode = GetLastError();
469         bbtkMessage("package",2,
470                 "Windows Error: [" << dwErrorCode <<"]"
471                 << std::endl);
472          
473         return 0;
474       }
475     
476     // Loads the Package bbtk version function 
477     std::string getvername(package_name);
478     getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
479     DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
480           
481     if (!getbbtkversion)
482       {
483         FreeLibrary(handler);
484         bbtkMessage("package",0,
485                     "BBTK ..ERROR.. loading shared library ["<<libname
486                     <<"] is not a valid bbtk package."
487                     <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
488         return 0;
489       }
490     
491     // version matches ?
492     if (getbbtkversion() != bbtk::GetVersion())
493       {
494                   FreeLibrary(handler);
495                   bbtkMessage("package",0,
496                                 "BBTK ..ERROR.. loading: "<<package_name
497                                 <<" - Shared library ["<<libname
498                                 <<"] was build with bbtk version "
499                                 <<getbbtkversion()
500                                 <<" but the current program runs with version "
501                                 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
502                   return 0;
503       }
504
505      // Loads the Package get function
506     std::string getpackname(package_name);
507     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
508     getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
509     if (!getpack)
510       {
511         FreeLibrary(handler);
512         bbtkMessage("package",0,
513                     "BBTK ..ERROR.. loading shared library ["<<libname
514                     <<"] is not a valid bbtk package."
515                     <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
516         return 0;
517       }
518     
519     // Loads the Package delete function
520     std::string delpackname(package_name);
521     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
522     delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
523     if (!delpack)
524       {
525         FreeLibrary(handler);
526         bbtkMessage("package",0,
527                     "BBTK ..ERROR.. loading shared library ["<<libname
528                     <<"] is not a valid bbtk package."
529                     <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
530         return 0;
531       }
532                                          
533 #else
534     bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
535 #endif
536     
537     return handler;
538   }
539   //==========================================================================
540   
541   //==========================================================================
542   /// Loads a package from a dynamic library
543   Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
544                                                      const std::string& pkgname,
545                                                      const std::string& path)
546   {
547 printf("EED Package::CreateFromDynamicLibrary Start \n");
548     bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
549                      <<libname<<")"<<std::endl);
550
551     DLGetPackageFunction gf;
552     DLDeletePackageFunction df;
553     DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
554                                                           pkgname,
555                                                           gf,df);
556     if (h==0) return Package::Pointer(); 
557     Package::Pointer p = gf();
558     p->mDynamicLibraryHandler = h;
559     p->mDLDeletePackageFunction = df;
560     
561     std::string separator =
562       ConfigurationFile::GetInstance().Get_file_separator ();
563     //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
564     std::string docreldoc = 
565       separator + "bbdoc" + separator + pkgname + separator + "index.html";
566     std::string reldoc = 
567       ".." + separator + ".." + docreldoc;
568     std::string doc = path + separator + ".." + separator
569       + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
570       + docreldoc;
571     
572     p->SetDocURL(doc);
573     p->SetDocRelativeURL(reldoc);
574     
575     bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
576                      <<libname<<") .. OK"<<std::endl);
577 printf("EED Package::CreateFromDynamicLibrary End \n");
578     return p;
579   }
580   //==========================================================================
581
582
583
584
585   //==========================================================================
586   /// UnLoads the package dynamic library (if any)
587   void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
588   {
589     if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
590       return;
591
592     std::string packname = pack.lock()->GetName();
593     bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
594                      <<packname<<"')"
595                      <<std::endl);
596
597     if (!pack.lock()->GetDescriptorMap().empty())
598       {
599
600         bbtkDebugMessage("package",5,"   Package not empty ... abort"
601                          <<std::endl);
602         return;
603         /*
604         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
605                         <<"DescriptorMap not empty "
606                         <<BBTK_INTERNAL_ERROR_MESSAGE);
607         */
608       }
609
610     if (pack.use_count()!=1)
611       {
612         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
613                         <<"empty dl package with external refs"
614                         <<BBTK_INTERNAL_ERROR_MESSAGE);
615       } 
616
617     if (doit) 
618       {
619         UnLoad(pack);
620         bbtkDebugMessage("package",5,"==> dynamic library for package '"
621                          <<packname<<"' closed"
622                          <<std::endl);    
623       }
624     else 
625       {
626         mReleasedDynamicallyLoadedPackages.insert(pack);
627         bbtkDebugMessage("package",1,"==> package '"<<packname
628                          <<"' put in the 'to unload' list"
629                          <<std::endl);
630       }
631
632     bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
633                      <<packname<<"')"
634                      <<std::endl); 
635   }
636   //==========================================================================
637
638   //==========================================================================
639   /// UnLoads released packages that were loaded dynamically
640   /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
641   void Package::UnLoadReleasedDynamicallyLoadedPackages()
642   {
643     bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
644
645     std::set<Package::WeakPointer>::iterator i;
646
647 //JCP- 21-04-09
648         if(mReleasedDynamicallyLoadedPackages.size()>0){
649                 for (i=mReleasedDynamicallyLoadedPackages.begin();
650                 i!=mReleasedDynamicallyLoadedPackages.end();
651                 ++i)
652                 {
653                 if (!i->expired()) UnLoad(*i);
654                 }
655         }
656 //JCP- 21-04-09
657     bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
658   }
659   //==========================================================================
660
661   //==========================================================================
662   void Package::UnLoad(Package::WeakPointer pack)
663   {
664     std::string packname = pack.lock()->GetName();
665     bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
666
667     Package* p = pack.lock().get();
668     
669     DynamicLibraryHandler h = p->mDynamicLibraryHandler;
670     
671     // deletes the package
672     p->mDLDeletePackageFunction();
673     
674     // closes the dl handler
675 #if defined(__GNUC__)  
676           if (dlclose(h)!=0)
677           {
678                   printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
679                   bbtkWarning("Failed to close dynamic library for package '"<<packname
680                                           <<"'"<<std::endl);
681           }  
682           
683 #elif defined(_WIN32)
684     FreeLibrary(h);
685 #endif
686
687     bbtkDebugMessage("package",1,"==> dynamic library for package '"
688                      <<packname<<"' closed"
689                      <<std::endl);    
690     bbtkDebugMessage("package",6,"   ... dynamic library unloaded"<<std::endl);
691   }
692   //==========================================================================
693
694         bool Package::ifBoxExist( std::string type)     
695     {
696                 bool ok=false;
697                 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
698                 if (i != mDescriptorMap.end())  
699                 {
700                         ok=true;
701                 }
702                 return ok;
703     }
704         
705   //==========================================================================
706   /// Creates an instance of a black box of type <type> with name <name>
707   BlackBox::Pointer Package::NewBlackBox(const std::string& type, 
708                                          const std::string& name) const
709   {
710     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
711     
712     DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
713     if (i == mDescriptorMap.end())  
714     {
715            bbtkDebugDecTab("kernel",8);
716            return BlackBox::Pointer();
717     }
718     BlackBox::Pointer bb =i->second->NewBlackBox(name);
719     bbtkDebugDecTab("kernel",8);
720     return bb;   
721
722   }
723   //==========================================================================
724
725
726
727   //==========================================================================
728   /// Creates an instance of an adaptor of input type <typein> and 
729   /// output type <typeout>  with name <name>
730   BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
731                                 const DataInfo& typeout,
732                                 const std::string& name) const
733   {
734     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
735                         ">::NewAdaptor("
736                         <<typein<<","
737                         <<typeout<<",\""
738                         <<name<<"\")"<<bbtkendl);
739
740     AdaptorKey key(typein,typeout,
741                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
742     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
743     if (i == mAdaptorMap.end())  
744       {
745         bbtkDebugDecTab("kernel",8);
746         return BlackBox::Pointer();
747       }
748     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
749     bbtkDebugDecTab("kernel",8);
750     return bb;   
751
752   }
753   //==========================================================================
754
755   //==========================================================================
756   /// Creates an instance of an adaptor of input type <typein> and 
757   /// output type <typeout>  with name <name>
758   BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
759                                       const DataInfo& typeout,
760                                       const std::string& name) const
761   {
762     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
763                         ">::NewWidgetAdaptor("
764                         <<typein<<","
765                         <<typeout<<",\""
766                         <<name<<"\")"<<bbtkendl);
767
768     AdaptorKey key(typein,typeout,
769                    BlackBoxDescriptor::DEFAULT_GUI);
770     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
771     if (i == mAdaptorMap.end())  
772       {
773         bbtkDebugDecTab("kernel",8);
774         return BlackBox::Pointer();
775       }
776     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
777     bbtkDebugDecTab("kernel",8);
778     return bb;   
779
780   }
781   //==========================================================================
782
783
784
785   //==========================================================================
786   /// Returns true is the package contains 
787   /// an adaptor of input type <typein> and 
788   /// output type <typeout>
789   /// If successfull then adaptor contains the black box type name
790   bool Package::FindWidgetAdaptor(const DataInfo& typein,
791                                   const DataInfo& typeout,
792                                   std::string& adaptor) const
793   {
794     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
795                         ">::FindWidgetAdaptor("
796                         <<typein<<","
797                         <<typeout<<")"<<bbtkendl);
798    
799     AdaptorKey key(/*typein*/
800                    DataInfo(typeid(void),""),
801                    typeout,
802                    BlackBoxDescriptor::DEFAULT_GUI);
803     // First try to find a single widget adaptor
804     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
805     if (i == mAdaptorMap.end())  
806       {
807         bbtkDebugDecTab("kernel",8);
808         return false;
809       }
810     adaptor = i->second.lock()->GetTypeName();
811     bbtkDebugDecTab("kernel",8);
812     return true;   
813
814   }
815   //==========================================================================
816
817
818
819   //==========================================================================
820   /// Returns true is the package contains 
821   /// an adaptor of input type <typein> and 
822   /// output type <typeout>
823   /// If successfull then adaptor contains the black box type name
824   bool Package::FindAdaptor(const DataInfo& typein,
825                             const DataInfo& typeout,
826                             std::string& adaptor) const
827   {
828     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
829                         ">::FindAdaptor("
830                         <<typein<<","
831                         <<typeout<<")"<<bbtkendl);
832     
833     AdaptorKey key(typein,typeout,
834                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
835     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
836     if (i == mAdaptorMap.end())  
837       {
838         bbtkDebugDecTab("kernel",8);
839         return false;
840       }
841     adaptor = i->second.lock()->GetTypeName();
842     bbtkDebugDecTab("kernel",8);
843     return true;   
844
845   }
846   //==========================================================================
847
848
849   //==========================================================================
850   /// Registers a black box descriptor in the package
851   bool Package::Register(BlackBoxDescriptor::Pointer d) 
852   {
853     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
854     
855     DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
856     if (i!=mDescriptorMap.end())
857       {
858         bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
859                     <<d->GetTypeName()<<"> which is already in the package");
860         return false;
861       }
862
863     mDescriptorMap[d->GetTypeName()] = d;
864     //    d->Reference();
865     d->SetPackage(GetThisPointer<Package>());
866     
867     // If it is a default adaptor, also register it in the adaptors map
868     if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
869       {
870         bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
871         
872         TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
873         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
874         DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
875         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
876         AdaptorKey key(infoin,infoout,d->GetKind());
877         
878         AdaptorMapType::const_iterator i;
879         i = mAdaptorMap.find(key);        
880         if (i == mAdaptorMap.end())  
881           {
882             mAdaptorMap[key] = d;
883           }
884         // If already an adaptor registered : error
885         else 
886           {
887             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
888               {
889                 bbtkError("Package <"<<GetName()<<
890                           "> : trying to register black box <"
891                           <<d->GetTypeName()
892                           <<"> as default adaptor but there is already a default adaptor registered (<"
893                           <<i->second.lock()->GetTypeName()<<">)");
894               }
895           }
896       }
897     // If it is a default adaptor, also register it in the adaptors map
898     else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
899       {
900         bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);   
901         
902         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
903         DataInfo infoin(typeid(void),"");
904         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
905         AdaptorKey key(infoin,infoout,d->GetKind());
906
907         AdaptorMapType::const_iterator i;
908         i = mAdaptorMap.find(key);        
909         if (i == mAdaptorMap.end())  
910           {
911             mAdaptorMap[key] = d;
912           }
913         // If already an adaptor registered : error
914         else 
915           {
916             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
917               {
918                 bbtkError("Package <"<<GetName()<<
919                           "> : trying to register black box <"
920                           <<d->GetTypeName()
921                           <<"> as default widget adaptor but there is already a default adaptor registered (<"
922                           <<i->second.lock()->GetTypeName()<<">)");
923               }
924           }
925       }
926     
927
928     bbtkDebugDecTab("kernel",8);
929    
930     return true;
931   }
932   //==========================================================================
933   
934   //===================================================================
935   void Package::Check() const
936   {
937     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
938                 <<" ["<<GetName()<<"]"<<std::endl);
939     DescriptorMapType::const_iterator i;
940     for (i=mDescriptorMap.begin();
941          i!=mDescriptorMap.end();
942          ++i) 
943       {
944         i->second->Check(true);
945       }
946     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
947                 <<" ["<<GetName()<<"] ... OK"<<std::endl);
948   }
949   //===================================================================
950
951
952   //==========================================================================
953   /// Changes the name of a black box type
954   void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
955   { 
956     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
957                         <<">::ChangeDescriptorName(\""<<oldname
958                         <<"\",\""<<newname<<"\")"<<std::endl);
959     // Looking into the bb map
960     DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
961     if (i == mDescriptorMap.end())  
962       {
963          bbtkDebugDecTab("kernel",8);
964          bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
965       }
966
967     i->second->SetTypeName(newname);
968     mDescriptorMap[newname] = i->second;
969     mDescriptorMap.erase(i);
970
971     bbtkDebugDecTab("kernel",8);    
972   }
973   //==========================================================================
974
975
976
977   //==========================================================================
978   void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
979   {
980     unsigned int lmax = 0;
981     std::vector<std::string> names;
982     std::vector<std::string> kinds;
983     std::vector<std::string> descrs;
984
985     DescriptorMapType::const_iterator i;
986     for (i=mDescriptorMap.begin();
987          i!=mDescriptorMap.end();
988          ++i) 
989       {
990         if ( adaptors || 
991              ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) 
992           {
993             std::string name("  ");
994             name += i->second->GetTypeName();
995             names.push_back(name);
996
997             std::string kind;
998             if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
999               {
1000                 kind = std::string("[A]");
1001               }
1002             else if ( i->second->GetKind() == 
1003                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
1004               {
1005                 kind = std::string("[DA]");
1006               }
1007             kinds.push_back(kind);
1008
1009             unsigned int l = name.size()+kind.size();
1010             if (l>lmax) lmax = l;
1011
1012             std::string descr;
1013             if (description) 
1014               {
1015                 descr += " : ";
1016                 descr += i->second->GetDescription();
1017               } 
1018             descrs.push_back(descr);
1019           }
1020       } 
1021     
1022
1023     std::string offs;
1024     offs.append(lmax+3,' ');
1025     std::vector<std::string>::iterator ni,ci,di;
1026     for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1027          ni != names.end(); ++ni, ++ci, ++di)
1028       {
1029         std::string space;
1030         space.append(lmax - ni->size() - ci->size(),' ');
1031         bbtkMessage("help",1,*ni << space << *ci );
1032         std::string d(*di);
1033         unsigned int dmax = 75 - lmax;
1034         //      while (d.size() > dmax ) 
1035         //  {
1036         if (d.size()>dmax) 
1037           bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1038         else 
1039           bbtkMessage("help",1,d << std::endl);
1040         //    d = d.substr(dmax,d.size());
1041         //  }
1042       }
1043
1044   }
1045   //==========================================================================
1046
1047   //==========================================================================
1048   /// Displays the list of adaptors of the package
1049   void Package::PrintHelpListAdaptors(bool description) const
1050   {
1051     DescriptorMapType::const_iterator i;
1052     for (i=mDescriptorMap.begin();
1053          i!=mDescriptorMap.end();
1054          ++i) 
1055       {
1056         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) 
1057           {
1058             bbtkMessage("help",1,
1059                         "  "<<i->second->GetTypeName());
1060             if ( i->second->GetKind() == 
1061                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
1062               {
1063                 bbtkMessage("help",1,
1064                             " [default]");
1065               }  
1066             if (description) 
1067               {
1068                 bbtkMessage("help",1,
1069                             " : "<<i->second->GetDescription());
1070
1071               } 
1072             bbtkMessage("help",1,std::endl);
1073           }
1074       } 
1075     /*
1076     AdaptorMapType::const_iterator i;
1077     for (i=mAdaptorMap.begin();
1078          i!=mAdaptorMap.end();
1079          ++i) 
1080       {
1081         bbtkMessage("help",1,
1082                     "  "<<i->second->GetTypeName());
1083         if (detail_level>0) 
1084           {
1085             bbtkMessage("help",1,
1086                         " : "<<i->second->GetDescription());
1087   
1088           } 
1089         bbtkMessage("help",1,std::endl);
1090       }
1091     */ 
1092   }
1093   //==========================================================================
1094
1095   //==========================================================================
1096   /// Prints help on a black box descriptor
1097   void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1098   {
1099     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1100                         <<">::PrintHelpDescriptor(\""
1101                         <<name<<"\")"<<bbtkendl);
1102
1103     DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1104     if (i == mDescriptorMap.end())  
1105       {
1106         bbtkDebugDecTab("kernel",8);
1107         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1108       }
1109     //    bbtkMessage("help",1,"["<<GetName()<<"] ");
1110     i->second->GetHelp(full);
1111     bbtkDebugDecTab("kernel",8);
1112
1113   }
1114   //==========================================================================
1115
1116
1117   //==========================================================================
1118   /// Returns true iff the package contains the box of name boxname
1119   bool Package::ContainsDescriptor(const std::string& name) const 
1120   {
1121     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1122                         <<">::ContainsDescriptor(\""
1123                         <<name<<"\")"<<bbtkendl);
1124     
1125     DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1126     if (i == mDescriptorMap.end())  
1127     {
1128       bbtkDebugDecTab("kernel",8);
1129       return false;
1130     }
1131     bbtkDebugDecTab("kernel",8);
1132     return true;
1133   }
1134   //==========================================================================
1135
1136
1137  
1138   //==========================================================================
1139   void Package::CreateHtmlPage(const std::string& filename,
1140                                const std::string& caller,
1141                                const std::string& source,
1142                                const std::string& custom_header,
1143                                const std::string& custom_title,
1144                                int detail, 
1145                                int level,
1146                                bool relative_link ) const
1147   {
1148     bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1149                         <<filename<<"\")"<<bbtkendl);
1150
1151 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1152
1153     //---------------------
1154     // Open output file
1155     std::ofstream s;
1156     s.open(filename.c_str());
1157     if (!s.good()) 
1158     {
1159        bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1160     }
1161     
1162     //----------------------
1163     // Html head
1164     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
1165
1166     if (custom_title.length() != 0) title = custom_title;
1167
1168     s << "<html lang=\"en\">\n";
1169     s << "<head>\n";
1170     s << "<title>" << title << "</title>\n";
1171     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1172     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1173     s << "<meta name=\"generator\" content=\"\">\n";
1174     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1175     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1176     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1177     s << "pre.display { font-family:inherit }\n";
1178     s << "pre.format  { font-family:inherit }\n";
1179     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1180     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
1181     s << "pre.smallexample { font-size:smaller }\n";
1182     s << "pre.smalllisp    { font-size:smaller }\n";
1183     s << "span.sc    { font-variant:small-caps }\n";
1184     s << "span.roman { font-family:serif; font-weight:normal; } \n";
1185     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
1186     s << "--></style>\n";
1187     s << "</head>\n";
1188     //----------------------
1189
1190     //----------------------
1191     // Html body
1192     s << "<body>\n";
1193     s << "<a name=\"Top\"></a>\n"; 
1194     
1195     //----------------------
1196     // Header
1197     if ( custom_header.length() != 0) 
1198       {
1199         if ( custom_header != "none" )
1200           { 
1201             std::ifstream in;
1202             in.open(custom_header.c_str());    
1203             if (!in.good()) 
1204               {
1205                 bbtkError("Could not open file \""<<custom_header<<"\"");
1206               }
1207             char buffer[512];
1208             while (!in.eof()) 
1209               {
1210                 in.getline(buffer,512);
1211                 std::string line(buffer);
1212                 s << line;
1213               }
1214             in.close();
1215             s << "<hr>\n";
1216            
1217             /*   
1218             s << "<object data=\"" << custom_header 
1219               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1220               << custom_header <<" could not be embedded.</object>\n";
1221             
1222             s << "<hr>\n";
1223             */
1224           }
1225       }
1226
1227     else 
1228       {
1229         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1230         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1231         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1232           << GetDescription() << "</TD></TR>\n";
1233         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1234           << GetAuthor() << "</TD></TR>\n";
1235         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1236           << GetCategory() << "</TD></TR>\n";
1237         s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1238           << GetVersion() << "</TD></TR>\n";
1239         s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1240           << bbtk::GetVersion() << "</TD></TR>\n";
1241         s << "</TABLE>\n";
1242       }
1243 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1244     //-------------------
1245     // Table of contents
1246     // Black boxes list
1247     //  s << "<div class=\"contents\">\n";
1248     s << "<p><b> Black Boxes : </b>\n";
1249     s << "<ul>\n";
1250
1251     s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1252
1253     DescriptorMapType::const_iterator i;
1254 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1255     for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1256                 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD) 
1257                         continue;
1258         
1259                 std::string name = i->second->GetTypeName();
1260                 Utilities::html_format(name);
1261                 std::string descr = i->second->GetDescription();
1262                 //Utilities::html_format(descr);
1263 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1264                 s << "<TR>";
1265                 s << "<TD style='vertical-align: top;'>";
1266                 s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1267                 <<"\" href=\"#"<<name<<"\">"
1268                 <<name<<"</a>";
1269                 s << "</TD> ";
1270                 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1271                 s << "</TR>\n";
1272                 }    
1273                 s << "</TABLE>\n";
1274
1275
1276                 s << "</ul>\n";
1277                 s << "</div>\n";
1278     
1279                 //-------------------
1280                 // Adaptors list
1281                 if (mAdaptorMap.size()>0) 
1282                 {
1283                         //  s << "<div class=\"contents\">\n";
1284                         s << "<p><b> Adaptors : </b>\n";
1285                         s << "<ul>\n";
1286 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1287                         //    DescriptorMapType::const_iterator i;
1288                         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1289                         for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i) 
1290                         {
1291                                 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) 
1292                                         continue;
1293     
1294                                 std::string name = i->second->GetTypeName();
1295                                 Utilities::html_format(name);
1296                                 std::string descr = i->second->GetDescription();
1297                     
1298                                 s << "<TR>";
1299                                 s << "<TD style='vertical-align: top;'>";
1300                                 s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1301                                   <<"\" href=\"#"<<name<<"\">"
1302                                   <<name<<"</a>";
1303                                 s << "</TD> ";
1304                                 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1305                                 s << "</TR>\n";
1306                         }    
1307                         s << "</TABLE>\n";
1308
1309                         s << "</ul>\n";
1310                         s << "</div>\n";
1311                 }
1312     
1313     
1314     //  s << "<div class=\"node\">\n";
1315
1316     //    s << "<p><hr>\n";
1317     //    s << "<a name=\"Top\"></a>\n";
1318     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1319     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1320     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
1321     
1322     //    s << "</div>\n";
1323
1324     //----------------------
1325     // Boxes doc
1326
1327     //-------------------
1328     // Computes output directory from filename to pass it to 
1329     // BlackBoxDescriptor::InsertHtmlHelp
1330                 std::string dir;
1331
1332                 std::string::size_type slash_position = filename.find_last_of("/\\");
1333
1334
1335                 if (slash_position != std::string::npos) {
1336                         if (slash_position == 0)
1337                          slash_position = 1;  
1338                         dir = filename.substr(0,slash_position);
1339                 }
1340
1341                 for (i=mDescriptorMap.begin();
1342                  i!=mDescriptorMap.end();
1343                  ++i) 
1344                 {
1345                         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1346                 }    
1347
1348     //----------------------
1349     // Footer 
1350     time_t rawtime;
1351     tm * ptm;
1352     time ( &rawtime );
1353     ptm = gmtime ( &rawtime );
1354
1355     s << "<p><hr>\n";
1356     s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1357       //      <<source<<"</b>
1358       <<"on "
1359       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
1360       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1361     s << "</body></html>\n"; 
1362     s.close();
1363     //----------------------
1364
1365     // End
1366     bbtkDebugDecTab("kernel",9);
1367   }
1368   //==========================================================================
1369   
1370   //==========================================================================
1371   std::string  Package::GetObjectName() const 
1372   { 
1373     return std::string("Package '")+mName+std::string("'"); 
1374   }
1375   //==========================================================================
1376
1377   //==========================================================================
1378   std::string Package::GetObjectInfo() const 
1379   {
1380     std::stringstream i;
1381     i << "  - "<<mDescriptorMap.size() << " boxes" << std::endl;
1382     if (mDynamicLibraryHandler) 
1383       {
1384         i<< "  - Loaded from dynamic library"<<std::endl;
1385       }
1386     return i.str();
1387   }
1388   //==========================================================================
1389
1390
1391   //==========================================================================
1392   size_t  Package::GetObjectSize() const 
1393   {
1394     size_t s = Superclass::GetObjectSize();
1395     s += Package::GetObjectInternalSize();
1396     return s;
1397   }
1398   //==========================================================================
1399   //==========================================================================
1400   size_t  Package::GetObjectInternalSize() const 
1401   {
1402     size_t s = sizeof(Package);
1403     return s;
1404   }
1405   //==========================================================================
1406   //==========================================================================
1407   size_t  Package::GetObjectRecursiveSize() const 
1408   {
1409     size_t s = Superclass::GetObjectRecursiveSize();
1410     s += Package::GetObjectInternalSize();
1411     
1412     DescriptorMapType::const_iterator i;
1413     for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1414       {
1415         s += i->second->GetObjectRecursiveSize();
1416       }
1417     return s;
1418   }
1419   //==========================================================================
1420   void  Package::GetBoxesInside(NodeTreeC& tree, int cont) 
1421   {
1422                 DescriptorMapType::const_iterator i;
1423                 std::cout<<"*********a********"<<std::endl;
1424                 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) 
1425                 {
1426                         i->second->GetBoxesInside(tree, cont);
1427                         std::cout<<"*****************"<<std::endl;
1428                 }    
1429   }
1430         //==========================================================================
1431   //==========================================================================
1432   std::set<Package::WeakPointer> 
1433   Package::mReleasedDynamicallyLoadedPackages;
1434   //==========================================================================
1435
1436 }
1437