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