CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2007 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #ifndef _Factory_hxx_ 00023 #define _Factory_hxx_ 00024 00025 #include <map> 00026 #include <string> 00027 #include <list> 00028 #include <set> 00029 #include <iostream> //TODO only for debugging 00030 00031 #include "Assert.hxx" 00032 #include "ErrFactory.hxx" 00033 #include "RunTimeLibraryLoader.hxx" 00034 00035 namespace CLAM { 00036 00068 template <typename AbstractProductType> 00069 class Factory 00070 { 00071 public: 00072 typedef AbstractProductType AbstractProduct; 00073 typedef std::string RegistryKey; 00074 00075 private: 00076 typedef std::string Attribute; 00077 typedef std::string Value; 00078 struct Pair 00079 { 00080 Attribute attribute; 00081 Value value; 00082 }; 00083 typedef RegistryKey Key; // TODO remove 00084 00085 public: 00086 typedef std::list<Key> Keys; 00087 typedef std::list<std::string> Values; 00088 typedef std::list<Pair> Pairs; 00089 00090 typedef AbstractProduct* (*CreatorMethod)(void); //TODO drop after refactoring 00091 00093 class Creator 00094 { 00095 public: 00096 virtual AbstractProductType* Create() = 0; 00097 virtual ~Creator(){}; 00098 }; 00099 00100 Factory() {}; 00101 ~Factory() {}; 00102 /* 00103 static Factory& GetInstance() { 00104 static Factory theInstance; 00105 return theInstance; 00106 } 00107 */ 00113 AbstractProduct* Create( const RegistryKey name ) 00114 { 00115 Creator& creator = _registry.GetCreator( name ); 00116 return creator.Create(); 00117 } 00118 00119 00120 00125 AbstractProduct* CreateSafe( const RegistryKey name ) throw (ErrFactory) 00126 { 00127 return _registry.GetCreatorSafe(name).Create(); 00128 } 00129 00130 00131 void Clear() 00132 { 00133 _registry.RemoveAllCreators(); 00134 } 00135 00136 void AddCreator(const RegistryKey name, Creator* creator) 00137 { 00138 _registry.AddCreator(name, creator); 00139 } 00140 00141 void AddCreatorWarningRepetitions(const RegistryKey name, Creator* creator) 00142 { 00143 _registry.AddCreatorWarningRepetitions(name, creator); 00144 } 00145 00146 void AddCreatorSafe(const RegistryKey name, Creator* creator) throw (ErrFactory) 00147 { 00148 _registry.AddCreatorSafe(name, creator); 00149 } 00150 00151 void DeleteCreator(const RegistryKey name) 00152 { 00153 _registry.DeleteCreator(name); 00154 } 00155 00156 void GetRegisteredNames( std::list<std::string>& namesList ) 00157 { 00158 _registry.GetRegisteredNames( namesList ); 00159 } 00160 00161 bool KeyExists( const RegistryKey& key) 00162 { 00163 return _registry.KeyExists(key); 00164 } 00165 00166 bool AttributeExists (const std::string& key, const std::string& attribute) 00167 { 00168 return _registry.AttributeExists(key,attribute); 00169 } 00170 00172 Keys GetKeys(const std::string& attribute, const std::string& value) 00173 { 00174 return _registry.GetKeys(attribute, value); 00175 } 00177 Keys GetKeys() 00178 { 00179 return GetKeys("",""); 00180 } 00182 Pairs GetPairsFromKey(const std::string& key) 00183 { 00184 return _registry.GetPairsFromKey(key); 00185 } 00188 Values GetSetOfValues(const std::string& attribute) 00189 { 00190 return _registry.GetSetOfValues(attribute); 00191 } 00193 Values GetValuesFromAttribute(const std::string& key, const std::string& attribute) 00194 { 00195 return _registry.GetValuesFromAttribute(key, attribute); 00196 } 00199 Value GetValueFromAttribute(const std::string& key, const std::string& attribute) 00200 { 00201 return GetValuesFromAttribute(key,attribute).front(); 00202 } 00203 00204 void AddAttribute(const std::string& key, const std::string& attribute, const std::string& value) 00205 { 00206 _registry.AddAttribute(key, attribute, value); 00207 } 00208 00209 public: // Inner classes. Public for better testing 00215 class Registry 00216 { 00217 private: 00218 struct FactoryEntry { 00219 Creator * creator; 00220 Pairs pairs; 00221 }; 00222 typedef std::map<Key, FactoryEntry> FactoryEntries; 00223 00224 public: 00225 Creator& GetCreator( RegistryKey creatorId) 00226 { 00227 CLAM_ASSERT(_factoryEntries.begin() != _factoryEntries.end(), 00228 "the Factory Registry shouldn't be empty"); 00229 00230 Creator* res = CommonGetCreator(creatorId); 00231 if (!res) 00232 { 00233 std::string errmsg("GetCreator invoked with a non existent key: "); 00234 errmsg += creatorId + "\nRegistered keys are:\n"; 00235 errmsg += GetRegisteredNames(); 00236 CLAM_ASSERT(res,errmsg.c_str()); 00237 } 00238 00239 return *res; 00240 } 00241 00242 Creator& GetCreatorSafe( RegistryKey creatorId) throw (ErrFactory) 00243 { 00244 if ( _factoryEntries.begin() == _factoryEntries.end() ) 00245 throw ErrFactory("GetCreatorSafe invoked on an empty registry"); 00246 00247 Creator* res = CommonGetCreator(creatorId); 00248 if (!res) 00249 { 00250 std::string msg("GetCreatorSafe invoked with a non existent key: "); 00251 msg += creatorId; 00252 msg += "\nRegistered keys are:\n"; 00253 msg += GetRegisteredNames(); 00254 throw ErrFactory(msg.c_str()); 00255 } 00256 return *res; 00257 } 00258 00259 void AddCreator( RegistryKey creatorId, Creator* creator ) 00260 { 00261 bool res = CommonAddCreator(creatorId, creator); 00262 if (!res) 00263 { 00264 std::string errmsg("Adding creator method in the factory: CreatorId '"); 00265 errmsg += creatorId + "' was already registered.\nRegistered keys are:\n"; 00266 errmsg += GetRegisteredNames(); 00267 CLAM_ASSERT(res, errmsg.c_str()); 00268 } 00269 } 00270 void AddCreatorWarningRepetitions( RegistryKey creatorId, Creator* creator ) 00271 { 00272 bool res = CommonAddCreator(creatorId, creator); 00273 if (!res) 00274 { 00275 std::string errmsg("WARNING. While adding a creator method in the factory, id '"); 00276 errmsg += creatorId + "' was already registered."; 00277 // errmsg += "\n Registered keys: " + GetRegisteredNames(); 00278 CLAM_WARNING(false, errmsg.c_str() ); 00279 } 00280 } 00281 00282 void AddCreatorSafe( RegistryKey creatorId, Creator* creator ) throw (ErrFactory) 00283 { 00284 if( !CommonAddCreator( creatorId, creator ) ) 00285 throw ErrFactory("A repeated key was passed"); 00286 } 00287 00288 void DeleteCreator( RegistryKey creatorId) 00289 { 00290 if (CommonDeleteCreator(creatorId)==false) 00291 std::cout<<"WARNING: attempted to delete an inexistent creator"<<std::endl; 00292 } 00293 00294 void RemoveAllCreators() 00295 { 00296 _factoryEntries.clear(); 00297 } 00298 00299 std::size_t Count() { return _factoryEntries.size(); } 00300 00301 void GetRegisteredNames( std::list<RegistryKey>& namesList ) 00302 { 00303 typename FactoryEntries::const_iterator i; 00304 00305 for ( i = _factoryEntries.begin(); i != _factoryEntries.end(); i++ ) 00306 { 00307 namesList.push_back( i->first ); 00308 } 00309 } 00310 std::string GetRegisteredNames() 00311 { 00312 std::string result; 00313 typedef std::list<RegistryKey> Names; 00314 Names names; 00315 GetRegisteredNames(names); 00316 for(Names::iterator it=names.begin(); it!=names.end(); it++) 00317 { 00318 result += (*it)+", "; 00319 } 00320 return result; 00321 00322 } 00323 00324 bool KeyExists(const RegistryKey& key) 00325 { 00326 typename FactoryEntries::const_iterator it = _factoryEntries.find(key); 00327 if(it == _factoryEntries.end()) 00328 { 00329 return false; 00330 } 00331 return true; 00332 } 00333 bool AttributeExists(const std::string& key, const std::string& attribute) 00334 { 00335 Pairs pairsFromKey = GetPairsFromKey(key); 00336 typename Pairs::const_iterator itPairs; 00337 for (itPairs=pairsFromKey.begin();itPairs!=pairsFromKey.end();itPairs++) 00338 { 00339 if (itPairs->attribute==attribute) return true; 00340 } 00341 return false; 00342 } 00343 00345 Keys GetKeys(const std::string& attribute, const std::string& value) 00346 { 00347 Keys result; 00348 typename FactoryEntries::const_iterator it; 00349 for(it = _factoryEntries.begin(); it != _factoryEntries.end(); it++) 00350 { 00351 if( (attribute == "") ) 00352 { 00353 result.push_back(it->first); 00354 continue; 00355 } 00356 Pairs attributes = it->second.pairs; 00357 typename Pairs::const_iterator itAtt; 00358 for(itAtt = attributes.begin(); itAtt != attributes.end(); itAtt++) 00359 { 00360 if( ((*itAtt).attribute == attribute) && ((*itAtt).value == value) ) 00361 { 00362 result.push_back(it->first); 00363 } 00364 } 00365 } 00366 return result; 00367 } 00369 Keys GetKeys() 00370 { 00371 return GetKeys("",""); 00372 } 00374 Pairs GetPairsFromKey(const std::string& key) 00375 { 00376 Pairs attributes; 00377 typename FactoryEntries::const_iterator it = _factoryEntries.find(key); 00378 if(it!=_factoryEntries.end()) 00379 { 00380 attributes = it->second.pairs; 00381 } 00382 return attributes; 00383 } 00386 Values GetSetOfValues(const std::string& attribute) 00387 { 00388 std::set<Value> AttributeSet; 00389 std::set<Value>::const_iterator itSet; 00390 Values values; 00391 typename FactoryEntries::const_iterator it; 00392 for(it = _factoryEntries.begin(); it != _factoryEntries.end(); it++) 00393 { 00394 Pairs attributes = it->second.pairs; 00395 typename Pairs::const_iterator itAtt; 00396 for(itAtt = attributes.begin(); itAtt != attributes.end(); itAtt++) 00397 { 00398 if((*itAtt).attribute == attribute) 00399 { 00400 itSet = AttributeSet.find((*itAtt).value); 00401 if(itSet == AttributeSet.end()) 00402 { 00403 AttributeSet.insert((*itAtt).value); 00404 } 00405 } 00406 } 00407 } 00408 // keep using the ProcessingFactory::Values 00409 for(itSet = AttributeSet.begin(); itSet != AttributeSet.end(); itSet++) 00410 { 00411 values.push_back(*itSet); 00412 } 00413 return values; 00414 } 00416 Values GetValuesFromAttribute(const std::string& key, const std::string& attribute) 00417 { 00418 Values values; 00419 typename FactoryEntries::const_iterator it = _factoryEntries.find(key); 00420 if(it != _factoryEntries.end()) 00421 { 00422 typename Pairs::const_iterator itAtt; 00423 for(itAtt = it->second.pairs.begin(); itAtt != it->second.pairs.end(); itAtt++) 00424 { 00425 if((*itAtt).attribute == attribute) 00426 { 00427 values.push_back((*itAtt).value); 00428 } 00429 } 00430 } 00431 return values; 00432 } 00434 Value GetValueFromAttribute(const std::string& key, const std::string& attribute) 00435 { 00436 return GetValuesFromAttribute(key,attribute).front(); 00437 } 00438 00439 void AddAttribute(const std::string& key, const std::string& attribute, const std::string& value) 00440 { 00441 typename FactoryEntries::const_iterator it; 00442 it = _factoryEntries.find(key); 00443 /*if(!KeyExists(key)) // NOT NEEDED AFETER UNIFYING 00444 { 00445 std::cout << "[Factory] tryind to add metadata to a non-existing key \"" << key << "\"" << std::endl; 00446 // return; //pau: debugging: add metadata anyway. maybe factory registrator is about to be instantiated. 00447 }*/ 00448 00449 Pair pair; 00450 pair.attribute = attribute; 00451 pair.value = value; 00452 00453 _factoryEntries[key].pairs.push_back(pair); 00454 /*Pairs pairs; 00455 if(it == _factoryEntries.end()) // it's a new key: insert it in the _factoryEntries map 00456 { 00457 pairs.push_back(pair); 00458 _factoryEntries.insert( typename FactoryEntries::value_type( key, pairs ) ); 00459 00460 } 00461 else 00462 { 00463 _factoryEntries[key].push_back(pair); 00464 }*/ 00465 } 00466 00467 00468 private: // data 00469 FactoryEntries _factoryEntries; 00470 00471 // helper methods: 00472 Creator* CommonGetCreator( RegistryKey& creatorId ) 00473 { 00474 typename FactoryEntries::const_iterator i = 00475 _factoryEntries.find(creatorId); 00476 if ( i==_factoryEntries.end() ) // not found 00477 return 0; 00478 return i->second.creator; 00479 } 00480 00481 bool CommonAddCreator( RegistryKey& creatorId, Creator* creator) 00482 { 00483 FactoryEntry factoryEntry; 00484 Pairs pairs; 00485 factoryEntry.creator = creator; 00486 factoryEntry.pairs = pairs; 00487 // returns false if the key was repeated. 00488 typedef typename FactoryEntries::value_type ValueType; 00489 return _factoryEntries.insert( ValueType( creatorId, factoryEntry ) ).second; 00490 } 00491 00492 bool CommonDeleteCreator (RegistryKey& creatorId) 00493 { 00494 typename FactoryEntries::iterator i = 00495 _factoryEntries.find(creatorId); 00496 if ( i == _factoryEntries.end() ) //not found 00497 return false; 00498 Creator * creator = i->second.creator; 00499 delete creator; 00500 _factoryEntries.erase(i); 00501 return true; 00502 } 00503 }; 00504 00505 int Count() { return _registry.Count(); } 00506 00507 private: 00508 Registry _registry; 00509 }; 00510 00511 00521 template< typename TheFactoryType, typename ConcreteProductType> 00522 class FactoryRegistrator 00523 { 00524 typedef typename TheFactoryType::AbstractProduct AbstractProduct; 00525 typedef typename TheFactoryType::RegistryKey RegistryKey; 00526 public: 00527 FactoryRegistrator( const char* metadata[] ) 00528 { 00529 CLAM_ASSERT(std::string(metadata[0])==std::string("key"), "FactoryRegistrator: first char* metadata should be 'key'"); //TODO fix 00530 CLAM_ASSERT(metadata[1], "FactoryRegistrator: value for first attriute ('key') must not be 0"); 00531 std::string key = metadata[1]; 00532 00533 TheFactoryType & factory = TheFactoryType::GetInstance(); 00534 factory.AddCreatorWarningRepetitions( key, new ConcreteCreator() ); 00535 std::string attribute, value; 00536 for(unsigned i = 2; metadata[i]; i++) 00537 { 00538 if(!metadata[i+1]) 00539 { 00540 std::cout << "[METADATA] error with attribute \"" << metadata[i] << "\"" << std::endl; 00541 } 00542 attribute = metadata[i]; 00543 value = metadata[++i]; 00544 factory.AddAttribute(key, attribute, value); 00545 } 00546 const std::string & libraryFileName=RunTimeLibraryLoader::FileOfSymbol(this); 00547 if (libraryFileName!="") 00548 factory.AddAttribute(key,"library",libraryFileName); 00549 } 00550 00551 FactoryRegistrator( RegistryKey key, TheFactoryType& fact ) 00552 { 00553 // std::cout << "FactoryRegistrator(key,factory) " << key << std::endl; 00554 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() ); 00555 } 00556 00557 FactoryRegistrator( TheFactoryType& fact ) 00558 { 00559 ConcreteProductType dummy; 00560 RegistryKey key=dummy.GetClassName(); 00561 // std::cout << "FactoryRegistrator(factory) " << dummy.GetClassName() << std::endl; 00562 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() ); 00563 } 00564 00565 FactoryRegistrator( RegistryKey key ) 00566 { 00567 // std::cout << "FactoryRegistrator(key) " << key << std::endl; 00568 TheFactoryType::GetInstance().AddCreatorWarningRepetitions( key, new ConcreteCreator() ); 00569 } 00570 00571 /* 00572 FactoryRegistrator( ) 00573 { 00574 ConcreteProductType dummy; 00575 RegistryKey key=dummy.GetClassName(); 00576 // std::cout << "FactoryRegistrator() " << key << std::endl; 00577 TheFactoryType::GetInstance().AddCreatorWarningRepetitions( key, new ConcreteCreator() ); 00578 } 00579 */ 00580 ~FactoryRegistrator() 00581 { 00582 // std::cout << "~FactoryRegistrator() " << std::endl; 00583 } 00584 00585 class ConcreteCreator : public TheFactoryType::Creator 00586 { 00587 public: 00588 AbstractProduct *Create() 00589 { 00590 return new ConcreteProductType(); 00591 } 00592 00593 }; 00594 }; 00595 00596 } // namespace 00597 00598 #endif // _Factory_hxx_ 00599