generateDoc.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "generateDoc.h"
00028
00029 #include <fstream>
00030
00031 #include <sofa/core/ObjectFactory.h>
00032 #include <sofa/core/objectmodel/Context.h>
00033 #include <sofa/simulation/common/Colors.h>
00034
00035 namespace projects
00036 {
00037
00038 bool generateFactoryHTMLDoc(const std::string& filename)
00039 {
00040
00041 std::ofstream ofile(filename.c_str());
00042 ofile << "<html><body>\n";
00043 sofa::core::ObjectFactory::getInstance()->dumpHTML(ofile);
00044 ofile << "</body></html>\n";
00045
00046 return true;
00047 }
00048
00049 static std::string xmlencode(const std::string& str)
00050 {
00051 std::string res;
00052 for (unsigned int i=0; i<str.length(); ++i)
00053 {
00054 switch(str[i])
00055 {
00056 case '<': res += "<"; break;
00057 case '>': res += ">"; break;
00058 case '&': res += "&"; break;
00059 case '"': res += """; break;
00060 case '\'': res += "'"; break;
00061 default: res += str[i];
00062 }
00063 }
00064 return res;
00065 }
00066
00067
00068
00069
00070
00071
00072 static const char* baseClasses[] =
00073 {
00074
00075
00076 "BehaviorModel",
00077 "CollisionModel",
00078 "VisualModel",
00079 "Mapping",
00080 "MechanicalState",
00081 "MechanicalMapping",
00082 "MasterSolver",
00083 "OdeSolver",
00084 "Mass",
00085 "ForceField",
00086 "InteractionForceField",
00087 "Constraint",
00088
00089 "Topology",
00090 "ContextObject",
00091 NULL
00092 };
00093
00094 #if 0
00095 class DummyObjectDescription : public sofa::core::objectmodel::BaseObjectDescription
00096 {
00097 protected:
00098 std::string name;
00099 AttributeMap attributes;
00100 sofa::core::objectmodel::BaseObjectDescription* parent;
00101 public:
00102 DummyObjectDescription()
00103 : name ("dummy")
00104 {
00105 parent = this;
00106 }
00107
00109 virtual sofa::core::objectmodel::Base* getObject() { return NULL; }
00110
00112 virtual const std::string& getName() const { return name; }
00113
00115 virtual sofa::core::objectmodel::BaseObjectDescription* getParent() const { return parent; }
00116
00118 virtual const AttributeMap& getAttributeMap() const { return attributes; }
00119
00121 virtual sofa::core::objectmodel::BaseObjectDescription* find(const char* , bool =false) { return this; }
00122
00123 virtual std::string getFullName() { return name; }
00124
00126 virtual sofa::core::objectmodel::Base* findObject(const char* ) { return NULL; }
00127
00128 };
00129 #endif
00130
00131 bool generateFactoryPHPDoc(const std::string& filename, const std::string& url)
00132 {
00133
00134 std::ofstream out(filename.c_str());
00135
00136 out << "<html><body>\n";
00137
00138 std::vector<std::string> templates;
00139 std::set<std::string> templateSet;
00140
00141 sofa::core::ObjectFactory::ClassEntry* mobject = sofa::core::ObjectFactory::getInstance()->getEntry("MechanicalObject");
00142 if (mobject)
00143 {
00144 for (std::list< std::pair< std::string, sofa::core::ObjectFactory::Creator* > >::iterator itc = mobject->creatorList.begin(), itcend = mobject->creatorList.end(); itc != itcend; ++itc)
00145 {
00146 if (itc->first.length() < 10)
00147 {
00148 templates.push_back(itc->first);
00149 templateSet.insert(itc->first);
00150 }
00151 }
00152 }
00153
00154 std::vector<sofa::core::ObjectFactory::ClassEntry*> classes;
00155 sofa::core::ObjectFactory::getInstance()->getAllEntries(classes);
00156
00157
00158
00159 std::map<std::string, std::vector<sofa::core::ObjectFactory::ClassEntry*> > sortedClasses;
00160 for (std::vector<sofa::core::ObjectFactory::ClassEntry*>::iterator it = classes.begin(), itend = classes.end(); it != itend; ++it)
00161 {
00162 sofa::core::ObjectFactory::ClassEntry* entry = *it;
00163 std::string nameSpace = sofa::core::objectmodel::Base::decodeNamespaceName(entry->creatorList.begin()->second->type());
00164 sortedClasses[nameSpace].push_back(entry);
00165 }
00166
00167 out << "<?php $show=$_REQUEST['show']; ?>\n";
00168
00169 out << "<?php $desc=$_REQUEST['desc']; ?>\n";
00170
00171 out << "<?php $base=0; \n";
00172 for (const char** c = baseClasses; *c; ++c)
00173 out << " if ($show == '" << xmlencode(*c) << "') $base=1;\n";
00174 out << " if (!$show) $base=1; ?>\n";
00175
00176 out << "<h1><?php if (!$base) echo 'Component : '.$show; else if ($show) echo 'Registered Components : '.$show; else echo 'Registered Components' ?></h1>\n";
00177
00178 out << "<?php if ($base) { ?>";
00179
00180 out << "<p> <b>Filter by Base Class :</b> ";
00181
00182 out << "<?php if ($show) { echo '<a href=\""<<url<<"'.($desc?'?desc='.$desc:'').'\">'; ?>";
00183 out << "ALL";
00184 out << "<?php } if ($show) echo '</a>'; ?>";
00185 for (const char** c = baseClasses; *c; ++c)
00186 {
00187 out << " <span class=\"class-base-name\" style=\"background-color: " << sofa::simulation::Colors::getColor(*c) << ";\">";
00188 out << "<?php if ($show != '"<<xmlencode(*c)<<"') echo '<a href=\""<<url<<"?show="<<xmlencode(*c)<<"'.($desc?'&desc='.$desc:'').'\">'; ?>";
00189 out << *c;
00190 out << "<?php if ($show != '"<<xmlencode(*c)<<"') echo '</a>'; ?>";
00191 out << "</span>";
00192 }
00193 out << "</p>\n";
00194 out << "<p><?php if ($desc) echo '<a href=\""<<url<<"'.($show? ('?show='.$show) : '').'\">Hide Descriptions<a>'; else echo '<a href=\""<<url<<"'.($show? ('?show='.$show).'&desc=1' : '?desc=1').'\">Show Descriptions<a>'; ?></p>";
00195 out << "<?php } ?>";
00196
00197 out << "<table class=\"sofa-classes\" border=\"0\" cellspacing=\"0\" cellpadding=\"1\">\n";
00198
00199 int nbcol = 2 + templates.size() + 2;
00200
00201
00202 out << "<tr class=\"sofa-header\">";
00203 out << "<td class=\"sofa-base-header\">Base Class</td>";
00204 out << "<td class=\"sofa-name-header\">Class Name</td>";
00205 for (std::vector<std::string>::iterator itt = templates.begin(), ittend = templates.end(); itt != ittend; ++itt)
00206 out << "<td class=\"sofa-template-header\">"<<xmlencode(*itt)<<"</td>";
00207 out << "<td class=\"sofa-template-header\">Other</td>";
00208 out << "<td class=\"sofa-namespace-header\">Namespace</td>";
00209 out << "</tr>\n";
00210
00211 for (std::map< std::string, std::vector<sofa::core::ObjectFactory::ClassEntry*> >::iterator it1 = sortedClasses.begin(), it1end = sortedClasses.end(); it1 != it1end; ++it1)
00212 for (std::vector<sofa::core::ObjectFactory::ClassEntry*>::iterator it = it1->second.begin(), itend = it1->second.end(); it != itend; ++it)
00213 {
00214 sofa::core::ObjectFactory::ClassEntry* entry = *it;
00215
00216 out << "<?php if (!$show || $show=='"<<xmlencode(entry->className)<<"'";
00217 for (std::set<std::string>::iterator it = entry->baseClasses.begin(), itend = entry->baseClasses.end(); it != itend; ++it)
00218 if (entry->baseClasses.size()==1 || *it != "VisualModel")
00219 out << " || $show == '"<<xmlencode(*it)<<"'";
00220 out << ") { ?>\n";
00221
00222
00223 out << "<tr class=\"sofa-class\">";
00224 out << "<td class=\"sofa-base\" valign=\"top\">";
00225 for (std::set<std::string>::iterator it = entry->baseClasses.begin(), itend = entry->baseClasses.end(); it != itend; ++it)
00226 out << "<span class=\"class-base\" style=\"background-color: " << sofa::simulation::Colors::getColor((*it).c_str()) << ";\" alt=\"" << xmlencode(*it) << "\" title=\"" << xmlencode(*it) << "\"> </span>";
00227 out << "</td>";
00228
00229 out << "<td class=\"sofa-name\" valign=\"top\"><?php if ($base) echo '<a href=\""<<url<<"?show="<<xmlencode(entry->className)<<"'.($desc?'&desc='.$desc:'').'\" class=\"class-name\">'; else echo '<span class=\"class-name\">'; ?>" << xmlencode(entry->className) <<"<?php if ($base) echo '</a>'; else echo '</span>'; ?>\n";
00230 if (!entry->aliases.empty())
00231 {
00232 for (std::set<std::string>::iterator it = entry->aliases.begin(), itend = entry->aliases.end(); it != itend; ++it)
00233 out << "<br/><span class=\"class-alias\">" << xmlencode(*it) <<"</span>\n";
00234 }
00235 out << "</td>";
00236
00237 for (std::vector<std::string>::iterator itt = templates.begin(), ittend = templates.end(); itt != ittend; ++itt)
00238 {
00239 out << "<td class=\"sofa-template\" align=\"center\" valign=\"top\">";
00240 if (entry->defaultTemplate == *itt)
00241
00242 out << "<span class=\"class-template-default\" alt=\""<<xmlencode(*itt)<<" (default)\" title=\""<<xmlencode(*itt)<<" (default)\">*</span>";
00243 else if (entry->creatorMap.find(*itt)!=entry->creatorMap.end())
00244
00245 out << "<span class=\"class-template\" alt=\""<<xmlencode(*itt)<<"\" title=\""<<xmlencode(*itt)<<"\">*</span>";
00246 else
00247 out << "<span class=\"class-no-template\"> <span>";
00248 out << "</td>";
00249 }
00250 std::string others;
00251 for (std::list< std::pair< std::string, sofa::core::ObjectFactory::Creator* > >::iterator itc = entry->creatorList.begin(), itcend = entry->creatorList.end(); itc != itcend; ++itc)
00252 {
00253 if (!itc->first.empty() && templateSet.find(itc->first)==templateSet.end())
00254 {
00255 if (!others.empty())
00256 others += ", ";
00257 others += xmlencode(itc->first);
00258 if (itc->first == entry->defaultTemplate)
00259 others += " (default)";
00260 }
00261 }
00262 out << "<td class=\"sofa-template\" align=\"center\" valign=\"top\">";
00263 if (!others.empty())
00264
00265 out << "<span class=\"class-template-others\" alt=\""<<others<<"\" title=\""<<others<<"\">*</span>";
00266 else
00267 out << "<span class=\"class-no-template\"> <span>";
00268 out << "</td>";
00269 std::string nameSpace = it1->first;
00270 out << "<td class=\"sofa-namespace\" valign=\"top\">";
00271 out << "<span class=\"class-namespace\">"<< xmlencode(nameSpace) <<"</span>";
00272 out << "</td>";
00273 out << "</tr>\n";
00274 if ((!entry->description.empty() && entry->description.substr(0,4)!="TODO") || !entry->authors.empty() || !entry->license.empty())
00275 out << "<?php if ($desc || !$base) { ?>";
00276 else
00277 out << "<?php if (!$base) { ?>";
00278 out << "<tr class=\"sofa-description\">";
00279 out << "<td>";
00280 out << "</td>";
00281 out << "<td class=\"sofa-description\" colspan=\""<< nbcol-1 <<"\" >";
00282 if (!entry->description.empty() && entry->description.substr(0,4)!="TODO")
00283 out << "<div class=\"class-description\">"<<entry->description<<"</div>";
00284 if (!entry->authors.empty())
00285 out << "<div class=\"class-authors\">Authors: "<<entry->authors<<"</div>";
00286 if (!entry->license.empty())
00287 out << "<div class=\"class-license\">License: "<<entry->license<<"</div>";
00288 out << "<?php if (!$base) { echo '<a href=\"api?class="<<xmlencode(nameSpace)<<"::"<<xmlencode(entry->className)<<"\">Doxygen class documentation</a>'; } ?>";
00289 out << "</td>";
00290 out << "</tr>\n";
00291 out << "<?php if (!$base) { ?>";
00292
00293 out << "<tr class=\"sofa-fields-header\">";
00294 out << "<td></td>";
00295 out << "<td class=\"sofa-field-name-header\">Field Name</td>";
00296 out << "<td class=\"sofa-field-type-header\" colspan=\""<<templates.size() + 1<<"\">Type</td>";
00297 out << "<td class=\"sofa-field-value-header\">Value</td>";
00298 out << "</tr>\n";
00299
00300
00301 try {
00302 std::cerr << "Trying to instantiate "<<entry->className<<std::endl;
00303 sofa::core::ObjectFactory::Creator* creator = entry->creatorList.begin()->second;
00304
00305
00306 sofa::core::objectmodel::BaseObject* object = creator->createInstance(NULL, NULL);
00307 if (object == NULL)
00308 {
00309 std::cerr << "ERROR: Failed to instantiate "<<entry->className<<std::endl;
00310 }
00311 else
00312 {
00313 std::vector< std::pair<std::string, sofa::core::objectmodel::BaseData* > > fields = object->getFields();
00314 for (std::vector< std::pair< std::string, sofa::core::objectmodel::BaseData*> >::iterator itf = fields.begin(), itfend = fields.end(); itf != itfend; ++itf)
00315 {
00316 sofa::core::objectmodel::BaseData* f = itf->second;
00317 out << "<tr class=\"sofa-field\">";
00318 out << "<td></td>";
00319 out << "<td class=\"sofa-field-name\">";
00320 out << "<span class=\"field-name\">"<<xmlencode(itf->first)<<"</span>";
00321 out << "</td>";
00322 out << "<td class=\"sofa-field-type\" colspan=\""<<templates.size() + 1<<"\">";
00323 out << "<span class=\"field-type\">"<<xmlencode(f->getValueTypeString())<<"</span>";
00324 out << "</td>";
00325 out << "<td class=\"sofa-field-value\">";
00326 out << "<span class=\"field-value\">"<<xmlencode(f->getValueString())<<"</span>";
00327 out << "</td>";
00328 out << "</tr>\n";
00329 if (f->help && *f->help && strncmp(f->help,"TODO",4))
00330 {
00331 out << "<tr class=\"sofa-field-description\">";
00332 out << "<td></td>";
00333 out << "<td class=\"sofa-field-description\" colspan=\""<<nbcol - 1<<"\">";
00334 out << "<div class=\"field-description\">"<<f->help<<"</div>";
00335 out << "</td>";
00336 out << "</tr>\n";
00337 }
00338 }
00339 delete object;
00340 }
00341 } catch(...)
00342 {
00343 std::cerr << "ERROR: Exception raised while trying to instantiate "<<entry->className<<std::endl;
00344 }
00345 out << "</tr>\n";
00346 out << "<?php } ?>\n";
00347 out << "<?php } ?>\n";
00348 out << "<?php } ?>\n";
00349
00350 }
00351 out << "</table>\n";
00352
00353 out << "</body></html>\n";
00354
00355 return true;
00356 }
00357
00358 }