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