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