libFAUDES

Sections

Index

cfl_registry.cpp

Go to the documentation of this file.
00001 /** @file cfl_registry.cpp Runtime interface, registry for faudes types and functions */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2009 Ruediger Berndt
00006 Copyright (C) 2009 Thomas Moor
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021 
00022 
00023 
00024 #include "cfl_registry.h"
00025 #include "corefaudes.h"
00026 
00027 // auto install types
00028 #ifndef FAUDES_MUTE_RTIAUTOLOAD
00029 #include "allplugins.h"
00030 #include "rtiautoload.h"
00031 #include "rtiautoload.cpp"
00032 #endif
00033 
00034 namespace faudes{
00035 
00036 
00037 
00038 /*
00039 ********************************************************************
00040 ********************************************************************
00041 ********************************************************************
00042 
00043 Implemantation of faudes TypeRegistry
00044 
00045 ********************************************************************
00046 ********************************************************************
00047 ********************************************************************
00048 */
00049 
00050 // static members: ref to the only one instnace
00051 TypeRegistry* TypeRegistry::mpInstance = 0;
00052 
00053 // static member: access to signleton
00054 TypeRegistry* TypeRegistry::G(){
00055   // lazy initialization
00056   if(!mpInstance){
00057     FD_DRTI("TypeRegistry::G(): Constrtuct singleton");
00058     mpInstance = new TypeRegistry();
00059   }
00060   return(mpInstance);
00061 }
00062 
00063 // clear all
00064 void TypeRegistry::Clear(){
00065   // delete all typedefs contained in map
00066   std::map<std::string, TypeDefinition*>::iterator mit;
00067   for(mit = mNameToTypeDef.begin(); mit != mNameToTypeDef.end(); mit++){
00068     if(mit->second != NULL){
00069       delete mit->second;
00070       mit->second = NULL;
00071     }
00072   }
00073   // delete maps
00074   mNameToTypeDef.clear();
00075   mIdToTypeDef.clear();
00076 }
00077 
00078 // query number of entries
00079 int TypeRegistry::Size() const{
00080   return(mNameToTypeDef.size());
00081 }
00082 
00083 // read access on type map
00084 TypeRegistry::Iterator  TypeRegistry::Begin(void) const{
00085   return(mNameToTypeDef.begin());
00086 }
00087 
00088 // read access on type map
00089 TypeRegistry::Iterator TypeRegistry::End(void) const{
00090   return(mNameToTypeDef.end());
00091 }
00092 
00093 // insert new entry
00094 void TypeRegistry::Insert(TypeDefinition* pTypeDef){
00095   FD_DRTI("TypeRegistration::Insert(): definition for " << pTypeDef->Name());
00096   // test existence
00097   if(Exists(pTypeDef->Name())){
00098     std::stringstream err;
00099     err << "Cannot overwrite existing entry with type " << pTypeDef->Name() << std::endl;
00100     throw Exception("TypeRegistry::Insert()", err.str(), 46);
00101   }
00102   // record in main map
00103   mNameToTypeDef[pTypeDef->Name()]=pTypeDef;
00104   // record in id map (first entry wins)
00105   if(pTypeDef->Prototype())
00106     if(mIdToTypeDef.find(typeid(*(pTypeDef->Prototype())).name())==
00107        mIdToTypeDef.end())
00108     mIdToTypeDef[typeid(*(pTypeDef->Prototype())).name()]=pTypeDef;
00109 }
00110 
00111 
00112 // scan token stream for type definitions
00113 void TypeRegistry::MergeDocumentation(TokenReader& rTr) {
00114   FD_DRTI("TypeRegistration::MergeMergeDocumentation()");
00115   // scan file
00116   Token token;
00117   while(rTr.Peek(token)) {
00118     // continue on other tokens
00119     if(token.Type()!=Token::Begin) { rTr.Get(token); continue; }
00120     if(token.StringValue()!="TypeDefinition") {  rTr.Get(token); continue; }
00121     // found type def in file
00122     rTr.ReadBegin("TypeDefinition");
00123     rTr.Peek(token);
00124     std::string ftype=token.StringValue();
00125     // extract type name
00126     size_t pos=ftype.find("::");
00127     if(pos!=std::string::npos) ftype=ftype.substr(pos+2);
00128     // locate type def in map
00129     Iterator tit = mNameToTypeDef.find(ftype);
00130     // case 1: type exists: add documentaion
00131     if(tit!=mNameToTypeDef.end()) {
00132       tit->second->MergeDocumentationBody(rTr);
00133       rTr.ReadEnd("TypeDefinition");
00134       continue;
00135     }
00136     // case 2: type does not exist: insert fake entry
00137     TypeDefinition* tdef = new TypeDefinition(ftype);
00138     tdef->MergeDocumentationBody(rTr);
00139     Insert(tdef);
00140     rTr.ReadEnd("TypeDefinition");  
00141   }
00142 }
00143 
00144 // scan file for type definitions
00145 void TypeRegistry::MergeDocumentation(const std::string& rFileName) {
00146   TokenReader tr(rFileName);
00147   MergeDocumentation(tr);
00148 }
00149 
00150 
00151 // construct faudes object by typename
00152 Type* TypeRegistry::NewObject(const std::string& rName) const{
00153   FD_DRTI("TypeRegistry::NewObject(\"" << rName << "\")");
00154   Iterator mit=mNameToTypeDef.find(rName);
00155   if(mit == End()) {
00156     std::stringstream err;
00157     err << "Unknown Type " << rName << std::endl;
00158     throw Exception("TypeRegistry::NewObject()", err.str(), 47);
00159   }
00160   Type* res=mit->second->NewObject();
00161   if(!res) {
00162     std::stringstream err;
00163     err << "Failed to instatiate new " << rName << std::endl;
00164     throw Exception("TypeRegistry::NewObject()", err.str(), 47);
00165   }
00166   return res;
00167 }
00168 
00169 // construct faudes object by typed reference
00170 Type* TypeRegistry::NewObject(const Type& rType) const{
00171   FD_DRTI("TypeRegistry::NewObject(prototype): typeid " << typeid(rType).name());
00172   Iterator mit;
00173   mit=mIdToTypeDef.find(typeid(rType).name());
00174   if(mit == mIdToTypeDef.end()) {
00175     std::stringstream err;
00176     err << "Unknown type by reference" << std::endl;
00177     throw Exception("TypeRegistry::NewObject()", err.str(), 47);
00178   }
00179   return(rType.New());
00180 }
00181 
00182 // access type definition by type name
00183 const TypeDefinition& TypeRegistry::Definition(const std::string& rName) const{
00184   FD_DRTI("TypeRegistry::Definition( " << rName << " )");
00185   Iterator mit=mNameToTypeDef.find(rName);
00186   if(mit == End()) {
00187     std::stringstream err;
00188     err << "Type not found: \"" << rName << "\"";
00189     throw Exception("TypeRegistry::Definition()", err.str(), 46);
00190   }
00191   return(*(mit->second));
00192 }
00193 
00194 // access type definition by typed reference
00195 const TypeDefinition& TypeRegistry::Definition(const Type& rType) const{
00196   FD_DRTI("TypeRegistry::Definition(): typeid " << typeid(rType).name());
00197   Iterator mit;
00198   mit=mIdToTypeDef.find(typeid(rType).name());
00199   if(mit!=mIdToTypeDef.end()) return *(mit->second);
00200   std::stringstream err;
00201   err << "Type not found: " << typeid(rType).name();
00202   throw Exception("TypeRegistry::Definition()", err.str(), 46);
00203 }
00204 
00205 // access prototype by type name
00206 const Type* TypeRegistry::Prototype(const std::string& rName) const{
00207   FD_DRTI("TypeRegistry::Prototype( " << rName << " )");
00208   Iterator mit=mNameToTypeDef.find(rName);
00209   if(mit == End()) return 0;
00210   return(mit->second->Prototype());
00211 }
00212 
00213 // access type definition by typed reference
00214 const std::string& TypeRegistry::TypeName(const Type& rType) const{
00215   FD_DRTI("TypeRegistry::TypeName(): typeid " << typeid(rType).name());
00216   Iterator mit;
00217   mit=mIdToTypeDef.find(typeid(rType).name());
00218   if(mit!=mIdToTypeDef.end()) return mit->second->Name();
00219   static std::string empty("");
00220   return empty;
00221 }
00222 
00223 // test existsnce by type name
00224 bool TypeRegistry::Exists(const std::string& rName) const{
00225   return mNameToTypeDef.find(rName) != End();
00226 }
00227 
00228 // test existsnce by type name
00229 bool TypeRegistry::Exists(const Type& rType) const{
00230   return mIdToTypeDef.find(typeid(rType).name()) != mIdToTypeDef.end();
00231 }
00232 
00233 
00234 // token write (informative/debugging)
00235 void TypeRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00236   FD_DRTI("TypeRegistry::DoWrite(): file " << rTw.FileName());
00237   // ignore label and context
00238   (void) rLabel;
00239   (void) pContext;
00240   // doit
00241   rTw.WriteBegin("TypeRegistry");
00242   Iterator tit;
00243   for(tit=Begin();tit!=End();tit++) {
00244      // write type definition
00245      tit->second->Write(rTw);
00246   }
00247   rTw.WriteEnd("TypeRegistry");
00248 }
00249 
00250 
00251 /*
00252 ********************************************************************
00253 ********************************************************************
00254 ********************************************************************
00255 
00256 Implemantation of faudes FunctionRegistry
00257 
00258 ********************************************************************
00259 ********************************************************************
00260 ********************************************************************
00261 */
00262 
00263 // static members: ref to the only one instnace
00264 FunctionRegistry* FunctionRegistry::mpInstance = 0;
00265 
00266 // static member: access to signleton
00267 FunctionRegistry* FunctionRegistry::G(){
00268   // lazy initialization
00269   if(!mpInstance){
00270     FD_DRTI("FunctionRegistry::G(): Construct singleton");
00271     mpInstance = new FunctionRegistry();
00272   }
00273   return(mpInstance);
00274 }
00275 
00276 // clear all
00277 void FunctionRegistry::Clear(){
00278   // delete all functiondefs contained in map
00279   std::map<std::string, FunctionDefinition*>::iterator mit;
00280   for(mit = mNameToFunctionDef.begin(); mit != mNameToFunctionDef.end(); mit++){
00281     if(mit->second != NULL) {
00282       FD_DRTI("FunctionRegistry::Clear: removing " << mit->second->Name());
00283       delete mit->second;
00284       mit->second = NULL;
00285     }
00286   }
00287   // delete maps
00288   mNameToFunctionDef.clear();
00289   mIdToFunctionDef.clear();
00290 }
00291 
00292 // query number of entries
00293 int FunctionRegistry::Size() const{
00294   return(mNameToFunctionDef.size());
00295 }
00296 
00297 // read access on function map
00298 FunctionRegistry::Iterator  FunctionRegistry::Begin(void) const{
00299   return(mNameToFunctionDef.begin());
00300 }
00301 
00302 // read access on function map
00303 FunctionRegistry::Iterator FunctionRegistry::End(void) const{
00304   return(mNameToFunctionDef.end());
00305 }
00306 
00307 // insert new entry
00308 void FunctionRegistry::Insert(FunctionDefinition* pFunctionDef){
00309   FD_DRTI("FunctionRegistration::Insert(): definition for " << pFunctionDef->Name());
00310   // test existence
00311   if(Exists(pFunctionDef->Name())){
00312     std::stringstream err;
00313     err << "Cannot overwrite existing entry with function " << pFunctionDef->Name() << std::endl;
00314     throw Exception("FunctionRegistry::Insert()", err.str(), 46);
00315   }
00316   // record in map
00317   mNameToFunctionDef[pFunctionDef->Name()]=pFunctionDef;
00318   // record in id map
00319   if(pFunctionDef->Prototype())
00320     mIdToFunctionDef[typeid(*(pFunctionDef->Prototype())).name()]=pFunctionDef;
00321 }
00322 
00323 
00324 // scan token stream for function definitions
00325 void FunctionRegistry::MergeDocumentation(TokenReader& rTr) {
00326   FD_DRTI("FunctionRegistration::MergeDocumentation()");
00327   // scan file
00328   Token token;
00329   while(rTr.Peek(token)) {
00330     // continue on other tokens
00331     if(token.Type()!=Token::Begin) { rTr.Get(token); continue; }
00332     if(token.StringValue()!="FunctionDefinition") {  rTr.Get(token); continue; }
00333     // found function def in file
00334     rTr.ReadBegin("FunctionDefinition");
00335     rTr.Peek(token);
00336     std::string ffunction=token.StringValue();
00337     // extract function name
00338     size_t pos=ffunction.find("::");
00339     if(pos!=std::string::npos) ffunction=ffunction.substr(pos+2);
00340     // locate function def in map
00341     Iterator fit = mNameToFunctionDef.find(ffunction);
00342     // case 1: function exists: add documentaion
00343     if(fit!=mNameToFunctionDef.end()) {
00344       fit->second->MergeDocumentationBody(rTr);
00345       rTr.ReadEnd("FunctionDefinition");
00346       continue;
00347     }
00348     // case 2: function does not exist: insert fake entry
00349     FunctionDefinition* fdef = new FunctionDefinition(ffunction);
00350     fdef->MergeDocumentationBody(rTr);
00351     Insert(fdef);
00352     rTr.ReadEnd("FunctionDefinition");  
00353   }
00354 }
00355 
00356 // scan file for function definitions
00357 void FunctionRegistry::MergeDocumentation(const std::string& rFileName) {
00358   TokenReader tr(rFileName);
00359   MergeDocumentation(tr);
00360 }
00361 
00362 
00363 // construct faudes object by functionname
00364 Function* FunctionRegistry::NewFunction(const std::string& rName) const{
00365   FD_DRTI("FunctionRegistry::NewFunction(\"" << rName << "\")");
00366   Iterator mit=mNameToFunctionDef.find(rName);
00367   if(mit == End()) {
00368     std::stringstream err;
00369     err << "Unknown function " << rName << std::endl;
00370     throw Exception("FunctionRegistry::NewFunction()", err.str(), 47);
00371   }
00372   Function* res=mit->second->NewFunction();
00373   if(!res) {
00374     std::stringstream err;
00375     err << "Failed to instatiate new " << rName << std::endl;
00376     throw Exception("FunctionRegistry::NewFunction()", err.str(), 47);
00377   }
00378   return res;
00379 }
00380 
00381 // construct faudes object by function reference
00382 Function* FunctionRegistry::NewFunction(const Function& rFunction) const{
00383   FD_DRTI("FunctionRegistry::NewFunction(prototype): typeid " << typeid(rFunction).name());
00384   Iterator mit;
00385   mit=mIdToFunctionDef.find(typeid(rFunction).name());
00386   if(mit == mIdToFunctionDef.end()) {
00387     std::stringstream err;
00388     err << "Unknown function by reference" << std::endl;
00389     throw Exception("FunctionRegistry::NewFunction()", err.str(), 47);
00390   }
00391   return(rFunction.New());
00392 }
00393 
00394 // access function definition by function name
00395 const FunctionDefinition& FunctionRegistry::Definition(const std::string& rName) const{
00396   FD_DRTI("FunctionRegistry::Definition( " << rName << " )");
00397   Iterator mit=mNameToFunctionDef.find(rName);
00398   if(mit == End()) {
00399     std::stringstream err;
00400     err << "Function not found: " << rName;
00401     throw Exception("FunctionRegistry::Definition()", err.str(), 46);
00402   }
00403   return(*(mit->second));
00404 }
00405 
00406 // access function definition by functiond reference
00407 // todo: have function id map
00408 const FunctionDefinition& FunctionRegistry::Definition(const Function& rFunction) const{
00409   FD_DRTI("FunctionRegistry::Definition(): typeid " << typeid(rFunction).name());
00410   Iterator mit;
00411   mit=mIdToFunctionDef.find(typeid(rFunction).name());
00412   if(mit!=mIdToFunctionDef.end()) return *(mit->second);
00413   /*
00414   Iterator mit;
00415   for(mit = Begin(); mit != End(); mit++){
00416     if(typeid(rFunction) == typeid(*(mit->second->Prototype())))
00417       return *(mit->second);
00418   }
00419   */
00420   std::stringstream err;
00421   err << "Function not found: " << typeid(rFunction).name();
00422   throw Exception("FunctionRegistry::Definition()", err.str(), 46);
00423 }
00424 
00425 // test existsnce by function name
00426 bool FunctionRegistry::Exists(const std::string& rName) const{
00427   return mNameToFunctionDef.find(rName) != End();
00428 }
00429 
00430 // test existsnce by function name
00431 bool FunctionRegistry::Exists(const Function& rFunction) const{
00432   return mIdToFunctionDef.find(typeid(rFunction).name()) != mIdToFunctionDef.end();
00433 }
00434 
00435 
00436 // token write (informative/debugging)
00437 void FunctionRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00438   FD_DRTI("FunctionRegistry::DoWrite(): file " << rTw.FileName());
00439   // ignore label and context
00440   (void) rLabel;
00441   (void) pContext;
00442   // doit
00443   rTw.WriteBegin("FunctionRegistry");
00444   Iterator tit;
00445   for(tit=Begin();tit!=End();tit++) {
00446      // write function definition
00447      tit->second->Write(rTw);
00448   }
00449   rTw.WriteEnd("FunctionRegistry");
00450 }
00451 
00452 
00453 /*
00454 ********************************************************************
00455 ********************************************************************
00456 ********************************************************************
00457 
00458 Implemantation of LoadRegistry
00459 
00460 ********************************************************************
00461 ********************************************************************
00462 ********************************************************************
00463 */
00464 
00465 // load from file
00466 void LoadRegistry(const std::string& rPath) {
00467   FD_DRTI("LoadRegistry(" << rPath << ")");
00468   // default path
00469   std::string rtipath = rPath;
00470   if(rtipath=="") rtipath="../doc/registry/registry.rti";  // todo: plattform/configure
00471   // clear
00472   TypeRegistry::G()->Clear();
00473   FunctionRegistry::G()->Clear();
00474 
00475   // auto install types with rti file
00476 #ifndef FAUDES_MUTE_RTIAUTOLOAD
00477   LoadAutoregisteredTypes();
00478 #endif
00479 
00480   // install programmatic functions
00481   //FunctionRegistry::G()->Insert<RtiReachability>("Reachability Tests");
00482   //FunctionRegistry::G()->Insert<RtiIntegerSum>("IntegerSum");
00483 
00484   // allow build system load registry programmatic contributions defined in plugins
00485 #ifdef FAUDES_PLUGINS_RTILOAD
00486   FAUDES_PLUGINS_RTILOAD;
00487 #endif
00488 
00489   // auto install functions
00490 #ifndef FAUDES_MUTE_RTIAUTOLOAD
00491   LoadAutoregisteredFunctions();
00492 #endif
00493 
00494   // merge documentation
00495   TypeRegistry::G()->MergeDocumentation(rtipath);
00496   FunctionRegistry::G()->MergeDocumentation(rtipath);
00497 
00498   // test and report status
00499 #ifdef FAUDES_CHECKED
00500 #ifndef FAUDES_MUTE_RTIAUTOLOAD
00501   TypeRegistry::Iterator tit;
00502   for(tit=TypeRegistry::G()->Begin(); tit!=TypeRegistry::G()->End(); tit++) {
00503     // should have prototype
00504     if(tit->second->Prototype()==NULL) 
00505       FD_WARN("TypeRegistry: " << tit->second->Name() << " has no prototype");
00506   }
00507   FunctionRegistry::Iterator fit;
00508   for(fit=FunctionRegistry::G()->Begin(); fit!=FunctionRegistry::G()->End(); fit++) {
00509     // should have prototype
00510     if(fit->second->Prototype()==NULL) 
00511       FD_WARN("FunctionRegistry: " << fit->second->Name() << " has no prototype");
00512   }
00513 #endif
00514 #endif
00515 
00516   FD_DRTI("LoadRegistry(" << rPath << "): done");
00517 }
00518 
00519 // clear all
00520 void ClearRegistry(void) {
00521   FD_DRTI("ClearRegistry()");
00522   // clear
00523   FunctionRegistry::G()->Clear();
00524   TypeRegistry::G()->Clear();
00525 }
00526 
00527 // conveience access to singleton 
00528 Type* NewObject(const std::string& rTypeName) { return TypeRegistry::G()->NewObject(rTypeName);}
00529 const std::string& TypeName(const Type& rObject) { return TypeRegistry::G()->TypeName(rObject);}
00530 Function* NewFunction(const std::string& rFunctName) { return FunctionRegistry::G()->NewFunction(rFunctName);}
00531 
00532 
00533 } // namespace

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3