Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

Factory.h (Maintainer: Ole Schulz-Trieglaff, Chris Bielow)

Go to the documentation of this file.
00001   // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // --------------------------------------------------------------------------
00005 //                   OpenMS Mass Spectrometry Framework
00006 // --------------------------------------------------------------------------
00007 //  Copyright (C) 2003-2008 -- Oliver Kohlbacher, Knut Reinert
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Lesser General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //  This library is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //  Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with this library; if not, write to the Free Software
00021 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // --------------------------------------------------------------------------
00024 // $Maintainer: Ole Schulz-Trieglaff, Chris Bielow $
00025 // --------------------------------------------------------------------------
00026 
00027 #ifndef OPENMS_CONCEPT_FACTORY_H
00028 #define OPENMS_CONCEPT_FACTORY_H
00029 
00030 #include <OpenMS/CONCEPT/Exception.h>
00031 #include <OpenMS/CONCEPT/FactoryBase.h>
00032 #include <OpenMS/CONCEPT/SingletonRegistry.h>
00033 #include <OpenMS/DATASTRUCTURES/String.h>
00034 
00035 #include <map>
00036 #include <iostream>
00037 #include <typeinfo>
00038 
00039 namespace OpenMS
00040 {
00041   class String;
00042 
00048   template <typename FactoryProduct>
00049   class Factory
00050   : public FactoryBase
00051   {
00052     friend class singletonsNeedNoFriends; //some versions of gcc would warn otherwise
00053 
00054   private:
00056     typedef FactoryProduct* (*FunctionType)();
00057     typedef std::map<String, FunctionType> Map;
00058     typedef typename Map::const_iterator MapIterator;
00059     typedef Factory<FactoryProduct> FactoryType;
00060     
00062     virtual ~Factory(){}
00063 
00065     Factory()
00066     {
00067     }
00068 
00070     static Factory* instance_()
00071     {
00072       if (!instance_ptr_)
00073       {
00074         // name of this Factory
00075         String myName = typeid(FactoryType).name();
00076         
00077         //check if an instance of this kind of Factory already registered
00078         if (!SingletonRegistry::isRegistered(myName))
00079         {
00080           // if not registered yet ... add it
00081           instance_ptr_ = new Factory();
00082           // now, attention as ORDER of commands is important here:
00083           // first register the Factory
00084           SingletonRegistry::registerFactory(myName, instance_ptr_);
00085           // because this call, might use another instance of this factory, but we want the other instance to register the children with "US"
00086           FactoryProduct::registerChildren();
00087         }
00088         else
00089         {
00090           // get instance of this factory from registry
00091           instance_ptr_ = static_cast<FactoryType*> (SingletonRegistry::getFactory(myName));      
00092         }
00093       }
00094       return instance_ptr_;
00095     }
00096 
00097   public:
00098     
00100     static FactoryProduct* create(const String& name)
00101     {
00102       MapIterator it = instance_()->inventory_.find(name);
00103       if (it != instance_()->inventory_.end())
00104       {
00105         return (*(it->second))();
00106       }
00107       else 
00108       {
00109         throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "This FactoryProduct is not registered!",name.c_str());
00110       }
00111     }
00112     
00119     static void registerProduct(const String& name, const FunctionType creator)
00120     {
00121       instance_()->inventory_[name] = creator;
00122     }
00123     
00125     static bool isRegistered(const String& name)
00126     {
00127       if (instance_()->inventory_.find(name) != instance_()->inventory_.end())
00128       {
00129         return true;
00130       }
00131       return false;
00132     }
00133 
00135     static std::vector<String> registeredProducts()
00136     {
00137       std::vector<String> list;
00138       for (MapIterator it = instance_()->inventory_.begin(); it!=instance_()->inventory_.end(); ++it)
00139       {
00140         list.push_back(it->first);
00141       }
00142       return list;
00143     }
00144     
00145   private:
00146 
00147     Map inventory_;
00148     static Factory* instance_ptr_;
00149   };
00150   
00151   template<typename FactoryProduct> Factory<FactoryProduct>* Factory<FactoryProduct>::instance_ptr_ = 0;
00152     
00153 }
00154 #endif //OPENMS_CONCEPT_FACTORY_H

Generated Tue Apr 1 15:36:34 2008 -- using doxygen 1.5.4 OpenMS / TOPP 1.1