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
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;
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
00103
00104
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:
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
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
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
00443
00444
00445
00446
00447
00448 Pair pair;
00449 pair.attribute = attribute;
00450 pair.value = value;
00451
00452 _factoryEntries[key].pairs.push_back(pair);
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 }
00465
00466
00467 private:
00468 FactoryEntries _factoryEntries;
00469
00470
00471 Creator* CommonGetCreator( RegistryKey& creatorId )
00472 {
00473 typename FactoryEntries::const_iterator i =
00474 _factoryEntries.find(creatorId);
00475 if ( i==_factoryEntries.end() )
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
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() )
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'");
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
00555 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00556 }
00557
00558 FactoryRegistrator( TheFactoryType& fact )
00559 {
00560 ConcreteProductType dummy;
00561 RegistryKey key=dummy.GetClassName();
00562
00563 fact.AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00564 }
00565
00566 FactoryRegistrator( RegistryKey key )
00567 {
00568
00569 TheFactoryType::GetInstance().AddCreatorWarningRepetitions( key, new ConcreteCreator() );
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 ~FactoryRegistrator()
00582 {
00583
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 }
00598
00599 #endif // _Factory_hxx_
00600