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