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