00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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>
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;
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);
00091
00093 class Creator
00094 {
00095 public:
00096 virtual AbstractProductType* Create() = 0;
00097 virtual ~Creator(){};
00098 };
00099
00100 Factory() {};
00101 ~Factory() {};
00102
00103
00104
00105
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:
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
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
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
00444
00445
00446
00447
00448
00449 Pair pair;
00450 pair.attribute = attribute;
00451 pair.value = value;
00452
00453 _factoryEntries[key].pairs.push_back(pair);
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 }
00466
00467
00468 private:
00469 FactoryEntries _factoryEntries;
00470
00471
00472 Creator* CommonGetCreator( RegistryKey& creatorId )
00473 {
00474 typename FactoryEntries::const_iterator i =
00475 _factoryEntries.find(creatorId);
00476 if ( i==_factoryEntries.end() )
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
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() )
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'");
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
00554 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00555 }
00556
00557 FactoryRegistrator( TheFactoryType& fact )
00558 {
00559 ConcreteProductType dummy;
00560 RegistryKey key=dummy.GetClassName();
00561
00562 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00563 }
00564
00565 FactoryRegistrator( RegistryKey key )
00566 {
00567
00568 TheFactoryType::GetInstance().AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 ~FactoryRegistrator()
00581 {
00582
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 }
00597
00598 #endif // _Factory_hxx_
00599