libFAUDES

Sections

Index

rtiregistry.cpp

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

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6