Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:00:06

0001 #ifndef PluginManager_hh_included
0002 #define PluginManager_hh_included 1
0003 
0004 #include <map>
0005 #include <string>
0006 #include <vector>
0007 
0008 namespace hcal {
0009 
0010   /** \brief Base class for classes to be managed by the PluginManager.
0011       This class is provided to enable appropriate use of the dynamic_cast<> operator and
0012       to defince clearly the newInstance() operator of the plugin factory.
0013 
0014       \ingroup hcalBase
0015    */
0016   class Pluggable {
0017   public:
0018     /// A virtual destructor is required to establish the inheritance tree
0019     virtual ~Pluggable() = default;
0020   };
0021 
0022   /** \brief Class which is able to create instances of another class.
0023 
0024       The AbstractPluginFactory defines the interface of a Factory
0025       class used by the PluginManager.  In general, factories are
0026       defined in terms of an abstract base class (derived from
0027       Pluggable), and a concrete implementation class.  This
0028       architecture is used in the database interface, where
0029       ConfigurationDatabaseImpl is the base class and
0030       ConfigurationDatabaseImplMySQL is a concrete implementation.
0031       \ingroup hcalBase
0032   */
0033   class AbstractPluginFactory {
0034   public:
0035     virtual ~AbstractPluginFactory() = default;
0036     /** \brief Create a new instance of the class which this factory provides */
0037     virtual Pluggable* newInstance() = 0;
0038     /** \brief Get the name of the class which is considered the base for this factory's class.  
0039     In the example, this would be ConfigurationDatabaseImpl
0040     */
0041     virtual const char* getBaseClass() const = 0;
0042     /** \brief Get the name of the concrete class provided directly by this factory.
0043     In the example, this would be ConfigurationDatabaseImplMySQL
0044     */
0045     virtual const char* getDerivedClass() const = 0;
0046   };
0047 
0048   /** \brief Global resource for managing implementations of abstract interface classes.
0049 
0050   The PluginManager class is a central repository to register factory
0051   objects.  Each factory object can create objects of a class derived
0052   from Pluggable.  Such factories can be easily created from the
0053   PluginFactoryTemplate using the DECLARE_PLUGGABLE macro.  The user
0054   of the PluginManager should know what base class is required and may
0055   obtain a specific factory or get a list of all factories capable of
0056   supplying concrete objects derived from the specified base class.  
0057   \ingroup hcalBase
0058   */
0059   class PluginManager {
0060   public:
0061     /** \brief Register a new factory with the singleton plugin manager.  Each factory provides objects of a single class.
0062     \param baseClass Name of the abstract base class for objects provided by the factory.
0063     \param derivedClass Name of the concrete class for objects provided by the factory.
0064     \param factory Pointer to the factory object itself
0065     */
0066     static void registerFactory(const char* baseClass, const char* derivedClass, AbstractPluginFactory* factory);
0067     /** \brief Lookup a specific factory by base class and derived class name 
0068     \return NULL if the specified factory is not found
0069     */
0070     static AbstractPluginFactory* getFactory(const char* baseClass, const char* derivedClass);
0071     /** \brief Lookup all factories providing concrete objects from the specified base class
0072      */
0073     static void getFactories(const char* baseClass, std::vector<AbstractPluginFactory*>& factories);
0074 
0075   private:
0076     static std::map<std::string, std::map<std::string, AbstractPluginFactory*> >& factories();
0077   };
0078 
0079   /** \brief Templated generic plugin factory used by the DECLARE_PLUGGABLE macro 
0080       \ingroup hcalBase
0081    */
0082   template <class T>
0083   class PluginFactoryTemplate : public AbstractPluginFactory {
0084   public:
0085     PluginFactoryTemplate(const char* bc, const char* dc) : m_baseClass(bc), m_derivedClass(dc) {
0086       PluginManager::registerFactory(bc, dc, this);
0087     }
0088     ~PluginFactoryTemplate() override = default;
0089     Pluggable* newInstance() override { return new T; }
0090     const char* getBaseClass() const override { return m_baseClass; }
0091     const char* getDerivedClass() const override { return m_derivedClass; }
0092 
0093   private:
0094     const char* m_baseClass;
0095     const char* m_derivedClass;
0096   };
0097 
0098 }  // namespace hcal
0099 
0100 /** \def DECLARE_PLUGGABLE(BASECLASS,MYCLASS)
0101    \brief Utility macro which creates a static object specializing PluginFactoryTemplate for a specific class (base and concrete).
0102    \param BASECLASS Base class for the factory (not in quotes)
0103    \param MYCLASS Derived concrete class for the factory (not in quotes)
0104 
0105    \b Example:
0106    \code
0107    DECLARE_PLUGGABLE(hcal::ConfigurationDatabaseImpl,ConfigurationDatabaseImplMySQL)
0108    \endcode
0109    \ingroup hcalBase
0110 */
0111 #define DECLARE_PLUGGABLE(BASECLASS, MYCLASS) \
0112   static hcal::PluginFactoryTemplate<MYCLASS> hcal_plugin_##MYCLASS(#BASECLASS, #MYCLASS);
0113 
0114 #endif  // PluginManager_hh_included