]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
Allow user to always forget .bbs
[bbtk.git] / kernel / src / bbtkPackage.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/01/22 15:02:00 $
7   Version:   $Revision: 1.1 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See doc/license.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  *\file
20  *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
21  */
22 #include "bbtkPackage.h"
23 #include "bbtkMessageManager.h"
24 #include "bbtkConfigurationFile.h"
25 #include <fstream>
26 #include <time.h>
27 #include "bbtkUtilities.h"
28
29 namespace bbtk
30 {
31   //==========================================================================
32   /// Ctor with the name of the package
33   Package::Package(const std::string& name,
34                    const std::string& author,
35                    const std::string& description,
36                    const std::string& version,
37                    const std::string& BBTKVersion) 
38     : mName(name),
39       mAuthor(author),
40       mDescription(description),
41       mVersion(version),
42       mBBTKVersion(BBTKVersion)
43   {
44     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
45     char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
46     std::string url = default_doc_dir; 
47     if (c != '/' && c !='\\') url = url + "/";
48     url = url +  "doc_tmp/" + name + "/index.html";    
49     
50     SetDocURL(url);
51     SetDocRelativeURL("Relative url not set");
52
53     /*
54     std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
55     relurl += "/packages/"+name+"/bbdoc/index.html";
56     std::string url = ConfigurationFile::GetInstance().Get_url()
57       + relurl; 
58     SetDocURL(url);
59     SetDocRelativeURL(relurl);   
60     */
61
62     //    std::cout  << "   url=["<<url<<"]"<<std::endl;
63     //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
64     bbtkDebugMessage("Core",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
65   }
66   //==========================================================================
67
68
69
70   //==========================================================================
71   /// Dtor
72   Package::~Package()
73   {
74     bbtkDebugMessageInc("Core",7,"Package::~Package(\""<<mName<<"\")"<<bbtkendl);
75     BlackBoxMapType::const_iterator i;
76     for (i=mBlackBoxMap.begin();
77          i!=mBlackBoxMap.end();
78          ++i) 
79       {
80         delete i->second;
81       } 
82     // Adaptors are also stored in the black box map : hence already deleted
83     /*
84     AdaptorMapType::const_iterator j;
85     for (j=mAdaptorMap.begin();
86          j!=mAdaptorMap.end();
87          ++j) 
88       {
89         delete j->second;
90         }
91     */ 
92     bbtkDebugDecTab("Core",7);
93   }
94   //==========================================================================
95
96
97
98   //==========================================================================
99   /// Creates an instance of a black box of type <type> with name <name>
100   BlackBox* Package::NewBlackBox(const std::string& type, 
101                                     const std::string& name) const
102   {
103     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
104     
105     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
106     if (i == mBlackBoxMap.end())  
107       {
108         bbtkDebugDecTab("Core",8);
109         return 0;
110       }
111     BlackBox* bb =i->second->CreateInstance(name);
112     bbtkDebugDecTab("Core",8);
113     return bb;   
114
115   }
116   //==========================================================================
117
118
119
120   //==========================================================================
121   /// Creates an instance of an adaptor of input type <typein> and 
122   /// output type <typeout>  with name <name>
123   BlackBox* Package::NewAdaptor(TypeInfo typein,
124                                    TypeInfo typeout,
125                                    const std::string& name) const
126   {
127     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<
128                         ">::NewAdaptor(<"
129                         <<TypeName(typein)<<">,<"
130                         <<TypeName(typeout)<<">,\""
131                         <<name<<"\")"<<bbtkendl);
132
133     AdaptorKey key(typein,typeout);
134     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
135     if (i == mAdaptorMap.end())  
136       {
137         bbtkDebugDecTab("Core",8);
138         return 0;
139       }
140     BlackBox* bb =i->second->CreateInstance(name);
141     bbtkDebugDecTab("Core",8);
142     return bb;   
143
144   }
145   //==========================================================================
146
147
148
149
150   //==========================================================================
151   /// Registers a black box descriptor in the package
152   bool Package::RegisterBlackBox(BlackBoxDescriptor* d) 
153   {
154     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
155     
156     mBlackBoxMap[d->GetTypeName()] = d;
157     d->SetPackage(this);
158     
159     // If it is a default adaptor, also register it in the adaptors map
160     if ( d->GetCategory() == BlackBoxDescriptor::DEFAULT_ADAPTOR) 
161       {
162         TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
163         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
164         AdaptorKey key(typein,typeout);
165         AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
166         if (i == mAdaptorMap.end())  
167           {
168             bbtkDebugMessage("Core",8,"The box is an adaptor, inserting it in adaptors map ..."<<std::endl);       
169             mAdaptorMap[key] = d;
170           }
171         // If already an adaptor registered : error
172         else 
173           {
174             bbtkError("Package <"<<GetName()<<
175                       "> : trying to register black box <"
176                       <<d->GetTypeName()
177                       <<"> as default adaptor but there is already a default adaptor registered (<"
178                       <<i->second->GetTypeName()<<">)");
179           }
180         
181
182       }
183     
184     bbtkDebugDecTab("Core",8);
185    
186     return true;
187   }
188   //==========================================================================
189   
190
191   //==========================================================================
192   /// UnRegisters a black box descriptor from the package
193   void Package::UnRegisterBlackBox(const std::string& name) 
194   {
195     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
196     // Looking into the bb map
197     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
198     if (i == mBlackBoxMap.end())  
199       {
200         bbtkDebugDecTab("Core",8);
201         bbtkError("UnRegister : The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
202       }
203     mBlackBoxMap.erase(i);
204     // Is it also in the adaptors map ?
205     /*
206     AdaptorMapType::iterator j = mAdaptorMap.find(name);
207     if (j != mAdaptorMap.end())  
208       {
209         mAdaptorMap.erase(j);
210       }
211     */    
212     bbtkDebugDecTab("Core",8);    
213   }
214   //==========================================================================
215
216   //==========================================================================
217   /// Changes the name of a black box type
218   void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
219   { 
220     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
221     // Looking into the bb map
222     BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
223     if (i == mBlackBoxMap.end())  
224       {
225         bbtkDebugDecTab("Core",8);
226         bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
227       }
228
229     i->second->SetTypeName(newname);
230     mBlackBoxMap[newname] = i->second;
231     mBlackBoxMap.erase(i);
232
233     bbtkDebugDecTab("Core",8);    
234   }
235   //==========================================================================
236
237   /*
238
239   //==========================================================================
240   /// Registers an adaptor descriptor in the package
241   bool Package::RegisterAdaptor(BlackBoxDescriptor* d) 
242   {
243     bbtkDebugMessage("Core",8,"Package<"<<GetName()<<">::RegisterAdaptor(\""<<d->GetTypeName()<<"\")"<<std::endl);
244     
245     TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
246     TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
247     AdaptorKey key(typein,typeout);
248     
249     mAdaptorMap[key] = d;
250     return true;
251   }
252   //==========================================================================
253   */
254
255
256   //==========================================================================
257   /// Displays the list of black boxes of the package
258   void Package::PrintBlackBoxes(bool description, bool adaptors) const
259   {
260     unsigned int lmax = 0;
261     std::vector<std::string> names;
262     std::vector<std::string> categs;
263     std::vector<std::string> descrs;
264
265     BlackBoxMapType::const_iterator i;
266     for (i=mBlackBoxMap.begin();
267          i!=mBlackBoxMap.end();
268          ++i) 
269       {
270         if ( adaptors || 
271              ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD) ) 
272           {
273             std::string name("  ");
274             name += i->second->GetTypeName();
275             names.push_back(name);
276
277             std::string categ;
278             if ( i->second->GetCategory() == BlackBoxDescriptor::ADAPTOR )
279               {
280                 categ = std::string("[A]");
281               }
282             else if ( i->second->GetCategory() == 
283                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
284               {
285                 categ = std::string("[DA]");
286               }
287             categs.push_back(categ);
288
289             unsigned int l = name.size()+categ.size();
290             if (l>lmax) lmax = l;
291
292             std::string descr;
293             if (description) 
294               {
295                 descr += " : ";
296                 descr += i->second->GetDescription();
297               } 
298             descrs.push_back(descr);
299           }
300       } 
301     
302
303     std::string offs;
304     offs.append(lmax+3,' ');
305     std::vector<std::string>::iterator ni,ci,di;
306     for (ni = names.begin(), ci = categs.begin(), di = descrs.begin();
307          ni != names.end(); ++ni, ++ci, ++di)
308       {
309         std::string space;
310         space.append(lmax - ni->size() - ci->size(),' ');
311         bbtkMessage("Help",1,*ni << space << *ci );
312         std::string d(*di);
313         unsigned int dmax = 75 - lmax;
314         //      while (d.size() > dmax ) 
315         //  {
316         if (d.size()>dmax) 
317           bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
318         else 
319           bbtkMessage("Help",1,d << std::endl);
320         //    d = d.substr(dmax,d.size());
321         //  }   
322       }
323
324   }
325   //==========================================================================
326
327   //==========================================================================
328   /// Displays the list of adaptors of the package
329   void Package::PrintAdaptors(bool description) const
330   {
331     BlackBoxMapType::const_iterator i;
332     for (i=mBlackBoxMap.begin();
333          i!=mBlackBoxMap.end();
334          ++i) 
335       {
336         if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD ) 
337           {
338             bbtkMessage("Help",1,
339                         "  "<<i->second->GetTypeName());
340             if ( i->second->GetCategory() == 
341                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
342               {
343                 bbtkMessage("Help",1,
344                             " [default]");
345               }  
346             if (description) 
347               {
348                 bbtkMessage("Help",1,
349                             " : "<<i->second->GetDescription());
350                 
351               } 
352             bbtkMessage("Help",1,std::endl);
353           }
354       } 
355     /*
356     AdaptorMapType::const_iterator i;
357     for (i=mAdaptorMap.begin();
358          i!=mAdaptorMap.end();
359          ++i) 
360       {
361         bbtkMessage("Help",1,
362                     "  "<<i->second->GetTypeName());
363         if (detail_level>0) 
364           {
365             bbtkMessage("Help",1,
366                         " : "<<i->second->GetDescription());
367           
368           } 
369         bbtkMessage("Help",1,std::endl);
370       }
371     */ 
372   }
373   //==========================================================================
374
375   //==========================================================================
376   /// Prints help on a black box
377   void Package::HelpBlackBox(const std::string& name, bool full) const
378   {
379     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
380                         <<name<<"\")"<<bbtkendl);
381
382     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
383     if (i == mBlackBoxMap.end())  
384       {
385         bbtkDebugDecTab("Core",8);
386         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
387       }
388     //    bbtkMessage("Help",1,"["<<GetName()<<"] ");
389     i->second->GetHelp(full);
390     bbtkDebugDecTab("Core",8);
391
392   }
393   //==========================================================================
394
395
396   //==========================================================================
397   /// Returns true iff the package contains the box of name boxname
398   bool Package::ContainsBlackBox(const std::string& name) const 
399   {
400     bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
401                         <<name<<"\")"<<bbtkendl);
402     
403     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
404     if (i == mBlackBoxMap.end())  
405       {
406         bbtkDebugDecTab("Core",8);
407         return false;
408       }
409     bbtkDebugDecTab("Core",8);
410     return true;
411   }
412   //==========================================================================
413
414
415  
416   //==========================================================================
417   void Package::CreateHtmlPage(const std::string& filename,
418                                const std::string& caller,
419                                const std::string& source,       
420                                const std::string& custom_header,
421                                const std::string& custom_title,
422                                int detail, 
423                                int level,
424                                bool relative_link ) const
425   {
426     bbtkDebugMessageInc("Core",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
427                         <<filename<<"\")"<<bbtkendl);
428
429     //---------------------
430     // Open output file
431     std::ofstream s;
432     s.open(filename.c_str());
433     if (!s.good()) 
434       {
435         bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
436       }
437     
438     //----------------------
439     // Html head
440     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
441
442     if (custom_title.length() != 0) title = custom_title;
443
444     s << "<html lang=\"en\">\n";
445     s << "<head>\n";
446     s << "<title>" << title << "</title>\n";
447     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
448     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
449     s << "<meta name=\"generator\" content=\"\">\n";
450     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
451     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
452     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
453     s << "pre.display { font-family:inherit }\n";
454     s << "pre.format  { font-family:inherit }\n";
455     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
456     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
457     s << "pre.smallexample { font-size:smaller }\n";
458     s << "pre.smalllisp    { font-size:smaller }\n";
459     s << "span.sc    { font-variant:small-caps }\n";
460     s << "span.roman { font-family:serif; font-weight:normal; } \n";
461     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
462     s << "--></style>\n";
463     s << "</head>\n";
464     //----------------------
465
466     //----------------------
467     // Html body
468     s << "<body>\n";
469     s << "<a name=\"Top\"></a>\n"; 
470     
471     //----------------------
472     // Header
473     if ( custom_header.length() != 0) 
474       {
475         if ( custom_header != "none" )
476           { 
477             std::ifstream in;
478             in.open(custom_header.c_str());    
479             if (!in.good()) 
480               {
481                 bbtkError("Could not open file \""<<custom_header<<"\"");
482               }
483             char buffer[512];
484             while (!in.eof()) 
485               {
486                 in.getline(buffer,512);
487                 std::string line(buffer);
488                 s << line;
489               }
490             in.close();
491             s << "<hr>\n";
492            
493             /*   
494             s << "<object data=\"" << custom_header 
495               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
496               << custom_header <<" could not be embedded.</object>\n";
497             
498             s << "<hr>\n";
499             */
500           }
501       }
502
503     else 
504       {
505         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
506         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
507         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
508           << GetDescription() << "</TD></TR>\n";
509         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
510           << GetAuthor() << "</TD></TR>\n";
511         s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
512           << GetVersion() << "</TD></TR>\n";
513         s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
514           << GetBBTKVersion() << "</TD></TR>\n";
515         s << "</TABLE>\n";
516       }
517
518     //-------------------
519     // Table of contents
520     // Black boxes list
521     //  s << "<div class=\"contents\">\n";
522     s << "<p><b> Black Boxes : </b>\n";
523     s << "<ul>\n";
524
525     s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
526
527     BlackBoxMapType::const_iterator i;
528     for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) 
529       {
530         if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD) 
531           continue;
532         
533         std::string name = i->second->GetTypeName();
534         Utilities::html_format(name);
535         std::string descr = i->second->GetDescription();
536         
537         s << "<TR>";
538         s << "<TD style='vertical-align: top;'>";
539         s << "<li><a name=\"toc_"<<name
540           <<"\" href=\"#"<<name<<"\">"
541           <<name<<"</a>";
542         s << "</TD> ";
543         s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
544         s << "</TR>\n";
545       }    
546     s << "</TABLE>\n";
547     
548     
549     s << "</li></ul>\n";
550     s << "</div>\n";
551     
552     //-------------------
553     // Adaptors list
554     if (mAdaptorMap.size()>0) 
555       {
556         //  s << "<div class=\"contents\">\n";
557         s << "<p><b> Adaptors : </b>\n";
558         s << "<ul>\n";
559         
560         //    BlackBoxMapType::const_iterator i;
561         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
562         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) 
563           {
564             if ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD) 
565               continue;
566             
567             std::string name = i->second->GetTypeName();
568             Utilities::html_format(name);
569             std::string descr = i->second->GetDescription();
570             
571             s << "<TR>";
572             s << "<TD style='vertical-align: top;'>";
573             s << "<li><a name=\"toc_"<<name
574               <<"\" href=\"#"<<name<<"\">"
575               <<name<<"</a>";
576             s << "</TD> ";
577             s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
578             s << "</TR>\n";
579           }    
580         s << "</TABLE>\n";
581         
582         s << "</li></ul>\n";
583         s << "</div>\n";
584       }
585     
586     
587     //  s << "<div class=\"node\">\n";
588
589     //    s << "<p><hr>\n";
590     //    s << "<a name=\"Top\"></a>\n";
591     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
592     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
593     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
594     
595     //    s << "</div>\n";
596
597     //----------------------
598     // Boxes doc
599
600     //-------------------
601     // Computes output directory from filename to pass it to 
602     // BlackBoxDescriptor::InsertHtmlHelp
603     std::string dir;
604     std::string::size_type slash_position = 
605       filename.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
606     if (slash_position != std::string::npos) {
607       if (slash_position == 0)
608         slash_position = 1;  
609       dir = filename.substr(0,slash_position);
610     }
611
612     for (i=mBlackBoxMap.begin();
613          i!=mBlackBoxMap.end();
614          ++i) 
615       {
616         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
617       }    
618
619     //----------------------
620     // Footer 
621     time_t rawtime;
622     tm * ptm;
623     time ( &rawtime );
624     ptm = gmtime ( &rawtime );
625
626     s << "<p><hr>\n";
627     s << "Automatically generated by <b>"<<caller<<"</b> from <b>"
628       <<source<<"</b> on "
629       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
630       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
631     s << "</body></html>\n"; 
632     s.close();
633     //----------------------
634
635     // End
636     bbtkDebugDecTab("Core",9);
637   }
638   //==========================================================================
639 }
640