]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkPackage.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/02/08 07:39:49 $
7   Version:   $Revision: 1.7 $
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_temp_dir();
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 +  "temp_dir/" + 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("Kernel",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
65   }
66   //==========================================================================
67
68
69
70   //==========================================================================
71   /// Dtor
72   Package::~Package()
73   {
74     bbtkDebugMessageInc("Kernel",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("Kernel",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("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
104     
105     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
106     if (i == mBlackBoxMap.end())  
107     {
108            bbtkDebugDecTab("Kernel",8);
109            return 0;
110     }
111     BlackBox* bb =i->second->CreateInstance(name);
112     bbtkDebugDecTab("Kernel",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("Kernel",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("Kernel",8);
138         return 0;
139       }
140     BlackBox* bb =i->second->CreateInstance(name);
141     bbtkDebugDecTab("Kernel",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("Kernel",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->GetKind() == 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("Kernel",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     bbtkDebugDecTab("Kernel",8);
183    
184     return true;
185   }
186   //==========================================================================
187   
188
189   //==========================================================================
190   /// UnRegisters a black box descriptor from the package
191   void Package::UnRegisterBlackBox(const std::string& name) 
192   {
193     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
194     // Looking into the bb map
195     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
196     if (i == mBlackBoxMap.end())  
197     {
198        bbtkDebugDecTab("Kernel",8);
199        bbtkError("UnRegister : The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
200      }
201     mBlackBoxMap.erase(i);
202     // Is it also in the adaptors map ?
203     /*
204     AdaptorMapType::iterator j = mAdaptorMap.find(name);
205     if (j != mAdaptorMap.end())  
206       {
207          mAdaptorMap.erase(j);
208       }
209     */    
210     bbtkDebugDecTab("Kernel",8);    
211   }
212   //==========================================================================
213
214   //==========================================================================
215   /// Changes the name of a black box type
216   void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
217   { 
218     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
219     // Looking into the bb map
220     BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
221     if (i == mBlackBoxMap.end())  
222       {
223          bbtkDebugDecTab("Kernel",8);
224          bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
225       }
226
227     i->second->SetTypeName(newname);
228     mBlackBoxMap[newname] = i->second;
229     mBlackBoxMap.erase(i);
230
231     bbtkDebugDecTab("Kernel",8);    
232   }
233   //==========================================================================
234
235   /*
236
237   //==========================================================================
238   /// Registers an adaptor descriptor in the package
239   bool Package::RegisterAdaptor(BlackBoxDescriptor* d) 
240   {
241     bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterAdaptor(\""<<d->GetTypeName()<<"\")"<<std::endl);
242     
243     TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
244     TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
245     AdaptorKey key(typein,typeout);
246     
247     mAdaptorMap[key] = d;
248     return true;
249   }
250   //==========================================================================
251   */
252
253
254   //==========================================================================
255   /// Displays the list of black boxes of the package
256   void Package::PrintBlackBoxes(bool description, bool adaptors) const
257   {
258     unsigned int lmax = 0;
259     std::vector<std::string> names;
260     std::vector<std::string> kinds;
261     std::vector<std::string> descrs;
262
263     BlackBoxMapType::const_iterator i;
264     for (i=mBlackBoxMap.begin();
265          i!=mBlackBoxMap.end();
266          ++i) 
267       {
268         if ( adaptors || 
269              ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) 
270           {
271             std::string name("  ");
272             name += i->second->GetTypeName();
273             names.push_back(name);
274
275             std::string kind;
276             if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
277               {
278                 kind = std::string("[A]");
279               }
280             else if ( i->second->GetKind() == 
281                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
282               {
283                 kind = std::string("[DA]");
284               }
285             kinds.push_back(kind);
286
287             unsigned int l = name.size()+kind.size();
288             if (l>lmax) lmax = l;
289
290             std::string descr;
291             if (description) 
292               {
293                 descr += " : ";
294                 descr += i->second->GetDescription();
295               } 
296             descrs.push_back(descr);
297           }
298       } 
299     
300
301     std::string offs;
302     offs.append(lmax+3,' ');
303     std::vector<std::string>::iterator ni,ci,di;
304     for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
305          ni != names.end(); ++ni, ++ci, ++di)
306       {
307         std::string space;
308         space.append(lmax - ni->size() - ci->size(),' ');
309         bbtkMessage("Help",1,*ni << space << *ci );
310         std::string d(*di);
311         unsigned int dmax = 75 - lmax;
312         //      while (d.size() > dmax ) 
313         //  {
314         if (d.size()>dmax) 
315           bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
316         else 
317           bbtkMessage("Help",1,d << std::endl);
318         //    d = d.substr(dmax,d.size());
319         //  }
320       }
321
322   }
323   //==========================================================================
324
325   //==========================================================================
326   /// Displays the list of adaptors of the package
327   void Package::PrintAdaptors(bool description) const
328   {
329     BlackBoxMapType::const_iterator i;
330     for (i=mBlackBoxMap.begin();
331          i!=mBlackBoxMap.end();
332          ++i) 
333       {
334         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) 
335           {
336             bbtkMessage("Help",1,
337                         "  "<<i->second->GetTypeName());
338             if ( i->second->GetKind() == 
339                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
340               {
341                 bbtkMessage("Help",1,
342                             " [default]");
343               }  
344             if (description) 
345               {
346                 bbtkMessage("Help",1,
347                             " : "<<i->second->GetDescription());
348
349               } 
350             bbtkMessage("Help",1,std::endl);
351           }
352       } 
353     /*
354     AdaptorMapType::const_iterator i;
355     for (i=mAdaptorMap.begin();
356          i!=mAdaptorMap.end();
357          ++i) 
358       {
359         bbtkMessage("Help",1,
360                     "  "<<i->second->GetTypeName());
361         if (detail_level>0) 
362           {
363             bbtkMessage("Help",1,
364                         " : "<<i->second->GetDescription());
365   
366           } 
367         bbtkMessage("Help",1,std::endl);
368       }
369     */ 
370   }
371   //==========================================================================
372
373   //==========================================================================
374   /// Prints help on a black box
375   void Package::HelpBlackBox(const std::string& name, bool full) const
376   {
377     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
378                         <<name<<"\")"<<bbtkendl);
379
380     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
381     if (i == mBlackBoxMap.end())  
382       {
383         bbtkDebugDecTab("Kernel",8);
384         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
385       }
386     //    bbtkMessage("Help",1,"["<<GetName()<<"] ");
387     i->second->GetHelp(full);
388     bbtkDebugDecTab("Kernel",8);
389
390   }
391   //==========================================================================
392
393
394   //==========================================================================
395   /// Returns true iff the package contains the box of name boxname
396   bool Package::ContainsBlackBox(const std::string& name) const 
397   {
398     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
399                         <<name<<"\")"<<bbtkendl);
400     
401     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
402     if (i == mBlackBoxMap.end())  
403     {
404       bbtkDebugDecTab("Kernel",8);
405       return false;
406     }
407     bbtkDebugDecTab("Kernel",8);
408     return true;
409   }
410   //==========================================================================
411
412
413  
414   //==========================================================================
415   void Package::CreateHtmlPage(const std::string& filename,
416                                const std::string& caller,
417                                const std::string& source,
418                                const std::string& custom_header,
419                                const std::string& custom_title,
420                                int detail, 
421                                int level,
422                                bool relative_link ) const
423   {
424     bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
425                         <<filename<<"\")"<<bbtkendl);
426
427     //---------------------
428     // Open output file
429     std::ofstream s;
430     s.open(filename.c_str());
431     if (!s.good()) 
432     {
433        bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
434     }
435     
436     //----------------------
437     // Html head
438     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
439
440     if (custom_title.length() != 0) title = custom_title;
441
442     s << "<html lang=\"en\">\n";
443     s << "<head>\n";
444     s << "<title>" << title << "</title>\n";
445     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
446     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
447     s << "<meta name=\"generator\" content=\"\">\n";
448     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
449     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
450     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
451     s << "pre.display { font-family:inherit }\n";
452     s << "pre.format  { font-family:inherit }\n";
453     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
454     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
455     s << "pre.smallexample { font-size:smaller }\n";
456     s << "pre.smalllisp    { font-size:smaller }\n";
457     s << "span.sc    { font-variant:small-caps }\n";
458     s << "span.roman { font-family:serif; font-weight:normal; } \n";
459     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
460     s << "--></style>\n";
461     s << "</head>\n";
462     //----------------------
463
464     //----------------------
465     // Html body
466     s << "<body>\n";
467     s << "<a name=\"Top\"></a>\n"; 
468     
469     //----------------------
470     // Header
471     if ( custom_header.length() != 0) 
472       {
473         if ( custom_header != "none" )
474           { 
475             std::ifstream in;
476             in.open(custom_header.c_str());    
477             if (!in.good()) 
478               {
479                 bbtkError("Could not open file \""<<custom_header<<"\"");
480               }
481             char buffer[512];
482             while (!in.eof()) 
483               {
484                 in.getline(buffer,512);
485                 std::string line(buffer);
486                 s << line;
487               }
488             in.close();
489             s << "<hr>\n";
490            
491             /*   
492             s << "<object data=\"" << custom_header 
493               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
494               << custom_header <<" could not be embedded.</object>\n";
495             
496             s << "<hr>\n";
497             */
498           }
499       }
500
501     else 
502       {
503         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
504         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
505         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
506           << GetDescription() << "</TD></TR>\n";
507         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
508           << GetAuthor() << "</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           << GetCategory() << "</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->GetKind() != 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         Utilities::html_format(descr);
537
538         s << "<TR>";
539         s << "<TD style='vertical-align: top;'>";
540         s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
541           <<"\" href=\"#"<<name<<"\">"
542           <<name<<"</a>";
543         s << "</TD> ";
544         s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
545         s << "</TR>\n";
546       }    
547     s << "</TABLE>\n";
548     
549     
550     s << "</ul>\n";
551     s << "</div>\n";
552     
553     //-------------------
554     // Adaptors list
555     if (mAdaptorMap.size()>0) 
556       {
557         //  s << "<div class=\"contents\">\n";
558         s << "<p><b> Adaptors : </b>\n";
559         s << "<ul>\n";
560
561         //    BlackBoxMapType::const_iterator i;
562         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
563         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) 
564           {
565             if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) 
566               continue;
567     
568             std::string name = i->second->GetTypeName();
569             Utilities::html_format(name);
570             std::string descr = i->second->GetDescription();
571     
572             s << "<TR>";
573             s << "<TD style='vertical-align: top;'>";
574             s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
575               <<"\" href=\"#"<<name<<"\">"
576               <<name<<"</a>";
577             s << "</TD> ";
578             s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
579             s << "</TR>\n";
580           }    
581         s << "</TABLE>\n";
582
583         s << "</ul>\n";
584         s << "</div>\n";
585       }
586     
587     
588     //  s << "<div class=\"node\">\n";
589
590     //    s << "<p><hr>\n";
591     //    s << "<a name=\"Top\"></a>\n";
592     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
593     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
594     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
595     
596     //    s << "</div>\n";
597
598     //----------------------
599     // Boxes doc
600
601     //-------------------
602     // Computes output directory from filename to pass it to 
603     // BlackBoxDescriptor::InsertHtmlHelp
604     std::string dir;
605     std::string::size_type slash_position = 
606       filename.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
607     if (slash_position != std::string::npos) {
608       if (slash_position == 0)
609          slash_position = 1;  
610       dir = filename.substr(0,slash_position);
611     }
612
613     for (i=mBlackBoxMap.begin();
614          i!=mBlackBoxMap.end();
615          ++i) 
616       {
617         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
618       }    
619
620     //----------------------
621     // Footer 
622     time_t rawtime;
623     tm * ptm;
624     time ( &rawtime );
625     ptm = gmtime ( &rawtime );
626
627     s << "<p><hr>\n";
628     s << "Automatically generated by <b>"<<caller<<"</b> from <b>"
629       <<source<<"</b> on "
630       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
631       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
632     s << "</body></html>\n"; 
633     s.close();
634     //----------------------
635
636     // End
637     bbtkDebugDecTab("Kernel",9);
638   }
639   //==========================================================================
640 }
641