LCOV - code coverage report
Current view: top level - src/libs/tools/include - plugindatabase.hpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 1 1 100.0 %
Date: 2019-09-12 12:28:41 Functions: 0 0 -

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Interface to all plugins
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : 
      11             : #ifndef TOOLS_PLUGIN_DATABASE_HPP
      12             : #define TOOLS_PLUGIN_DATABASE_HPP
      13             : 
      14             : #include <map>
      15             : #include <memory>
      16             : #include <unordered_map>
      17             : 
      18             : #include <kdb.hpp>
      19             : 
      20             : #include <pluginspec.hpp>
      21             : 
      22             : namespace kdb
      23             : {
      24             : 
      25             : namespace tools
      26             : {
      27             : 
      28             : /**
      29             :  * @brief Loads all plugins and allows us to query them.
      30             :  */
      31             : class PluginDatabase
      32             : {
      33             : protected:
      34             :         typedef void (*func_t) ();
      35             : 
      36             : public:
      37             :         /* TODO: reintroduce with next API break
      38             :         virtual ~PluginDatabase ()
      39             :         {
      40             :         }
      41             :         */
      42             : 
      43             :         /**
      44             :          * @brief list all plugins
      45             :          *
      46             :          * If Elektra is compiled with plugins, it will search for shared libraries.
      47             :          * In any case, if no shared libraries were found
      48             :          * it will fallback to an internal list (plugins that were compiled together with Elektra).
      49             :          *
      50             :          * @return a list of all available plugins
      51             :          */
      52             :         virtual std::vector<std::string> listAllPlugins () const = 0;
      53             : 
      54             :         // TODO: add additional functions:
      55             :         // virtual void registerPlugin(PluginSpec) = 0;
      56             :         // virtual std::vector<PluginSpec> listAllPlugins() const = 0;
      57             : 
      58             :         enum Status
      59             :         {
      60             :                 /// does not directly, but can be loaded via provides
      61             :                 provides,
      62             :                 /// exists and working as given
      63             :                 real,
      64             :                 /// does not exist or cannot be loaded
      65             :                 missing
      66             :         };
      67             : 
      68             :         virtual Status status (PluginSpec const & whichplugin) const = 0;
      69             : 
      70             :         /**
      71             :          * @brief lookup contract clauses or dynamic information
      72             :          *
      73             :          * @param whichplugin about which plugin?
      74             :          * @param which about which clause in the contract?
      75             :          *
      76             :          * @return the clause of the contract
      77             :          */
      78             :         virtual std::string lookupInfo (PluginSpec const & whichplugin, std::string const & which) const = 0;
      79             : 
      80             :         /**
      81             :          * @brief get exported plugin symbol
      82             :          *
      83             :          * @param whichplugin from which plugin?
      84             :          * @param which which symbol would you like to look up?
      85             :          *
      86             :          * @return the function pointer to the exported symbol or NULL if the symbol was not found
      87             :          */
      88             :         virtual func_t getSymbol (PluginSpec const & whichplugin, std::string const & which) const = 0;
      89             : 
      90             :         /**
      91             :          * @brief lookup which plugin handles metadata
      92             :          *
      93             :          * @param which the metadata of interest
      94             :          *
      95             :          * @return the best suited plugin specification which provides it
      96             :          */
      97             :         virtual PluginSpec lookupMetadata (std::string const & which) const = 0;
      98             : 
      99             :         /**
     100             :          * @brief lookup which plugin is a provider for that plugin
     101             :          *
     102             :          * @note will return a PluginSpec with getName() == provides if the string provides
     103             :          *       actually is a plugin name.
     104             :          *
     105             :          * @param provides is the provider to find
     106             :          *
     107             :          * @throw NoPlugin if no plugin that provides the functionality could be found
     108             :          *
     109             :          * @return the plugin itself or the best suited plugin specification which provides it
     110             :          */
     111             :         virtual PluginSpec lookupProvides (std::string const & provides) const = 0;
     112             : 
     113             :         /**
     114             :          * @brief looks up all plugins which are a suitable provider
     115             :          *
     116             :          * @note in case a plugin name is provided, the plugin with the name will also be
     117             :          *       part of the result. But if there are other plugins providing the requirement,
     118             :          *       then they will also be part of the result.
     119             :          *
     120             :          * @param provides is the provider to find
     121             :          *
     122             :          * @return a map of plugins with their status offering the requirement or are named after it
     123             :          */
     124             :         virtual std::map<int, PluginSpec> lookupAllProvidesWithStatus (std::string const & provides) const = 0;
     125             : 
     126             :         /**
     127             :          * @brief looks up all plugins which are a suitable provider
     128             :          *
     129             :          * @note in case a plugin name is provided, the plugin with the name will also be
     130             :          *       part of the result. But if there are other plugins providing the requirement,
     131             :          *       then they will also be part of the result.
     132             :          *       The ordering of the resulting vector has no special meaning.
     133             :          *
     134             :          * @param provides is the provider to find
     135             :          *
     136             :          * @return a vector of plugins offering the requirement or are named after it
     137             :          */
     138             :         virtual std::vector<PluginSpec> lookupAllProvides (std::string const & provides) const = 0;
     139             : 
     140             :         /**
     141             :          * @param statusString the string encoding the status
     142             :          *
     143             :          * @return The representing number for a given status.
     144             :          */
     145             :         static int calculateStatus (std::string statusString);
     146             : 
     147             :         static const std::map<std::string, int> statusMap;
     148             : };
     149             : 
     150             : typedef std::shared_ptr<PluginDatabase> PluginDatabasePtr;
     151             : 
     152             : /**
     153             :  * @brief A plugin database that works with installed modules
     154             :  */
     155             : class ModulesPluginDatabase : public PluginDatabase
     156             : {
     157             : protected:
     158             :         class Impl;
     159             :         std::unique_ptr<Impl> impl;
     160             : 
     161             : public:
     162             :         ModulesPluginDatabase ();
     163             :         ~ModulesPluginDatabase ();
     164             :         /* TODO: reintroduce with next API break
     165             :         virtual ~ModulesPluginDatabase ();
     166             :         */
     167             : 
     168             :         std::vector<std::string> listAllPlugins () const;
     169             :         PluginDatabase::Status status (PluginSpec const & whichplugin) const;
     170             :         std::string lookupInfo (PluginSpec const & spec, std::string const & which) const;
     171             :         func_t getSymbol (PluginSpec const & whichplugin, std::string const & which) const;
     172             :         PluginSpec lookupMetadata (std::string const & which) const;
     173             :         PluginSpec lookupProvides (std::string const & provides) const;
     174             :         std::map<int, PluginSpec> lookupAllProvidesWithStatus (std::string const & provides) const;
     175             :         std::vector<PluginSpec> lookupAllProvides (std::string const & provides) const;
     176             : };
     177             : 
     178             : class PluginVariantDatabase : public ModulesPluginDatabase
     179             : {
     180             :         class VariantImpl;
     181             :         std::unique_ptr<VariantImpl> variantImpl;
     182             : 
     183             : public:
     184             :         /**
     185             :          * @brief constructor that takes a configuration keyset for plugins
     186             :          *
     187             :          * takes the list of plugins provided by the ModulesPluginDatabase and
     188             :          * removes all plugins that are disabled in the system config which was
     189             :          * given to the constructor.
     190             :          *
     191             :          * example: removes the `simpleini` plugin if an entry like
     192             :          *
     193             :          *   system/elektra/plugins/simpleini/disable = 1
     194             :          *
     195             :          * exists in the keyset handed to the constructor
     196             :          *
     197             :          * @note the constructor should be called with a keyset containing
     198             :          * the keys for system/elektra/plugins
     199             :          *
     200             :          * @param conf keyset containing keys from system/elektra/plugins
     201             :          */
     202             :         explicit PluginVariantDatabase (const KeySet & conf);
     203             :         ~PluginVariantDatabase ();
     204             :         /* TODO: reintroduce with next API break
     205             :         virtual ~PluginVariantDatabase ();
     206             :         */
     207             : 
     208             :         std::vector<std::string> listAllPlugins () const;
     209             : 
     210             :         /**
     211             :          * @brief returns a list of plugin variants for the plugin
     212             :          *
     213             :          * takes the genconf function provided by plugins to generate variants.
     214             :          * variants can be disabled through the system configuration handed to
     215             :          * the constructor of the class.
     216             :          *
     217             :          * example: ignores a variant `spacesep` delivered by genconf if an entry like
     218             :          *
     219             :          *   system/elektra/plugins/simpleini/variants/spacesep/disable = 1
     220             :          *
     221             :          * exists in the keyset handed to the constructor
     222             :          *
     223             :          * @note if no plugin variant could be found, an empty vector will be returned.
     224             :          *
     225             :          * @param whichplugin is the plugin for which we want all variants
     226             :          *
     227             :          * @return a vector of plugin variants for the given plugin
     228             :          */
     229             :         std::vector<PluginSpec> getPluginVariants (PluginSpec const & whichplugin) const;
     230             : 
     231             : private:
     232             :         /**
     233             :          * @brief returns a list of plugin variants created from the system config
     234             :          *
     235             :          * considered are keys below system/elektra/plugins/<plugin>/variants
     236             :          *
     237             :          * @note variants listed in @p genconfToIgnore are not added to the result.
     238             :          * it is expected that they were added at another point already
     239             :          * (e.g. explicit override check).
     240             :          *
     241             :          * @param whichplugin is the plugin for which we want all variants
     242             :          * @param sysconf is a keyset containing the system config for system/elektra/plugins
     243             :          * @param genconfToIgnore is a keyset containing variants to ignore from the sysconf
     244             :          *
     245             :          * @return a vector of pluginspecs with variant configurations
     246             :          */
     247             :         std::vector<PluginSpec> getPluginVariantsFromSysconf (PluginSpec const & whichplugin, KeySet const & sysconf,
     248             :                                                               KeySet const & genconfToIgnore) const;
     249             : 
     250             :         /**
     251             :          * @brief returns a list of plugin variants created from the genconf config
     252             :          *
     253             :          * does take a keyset with config from the `genconf` plugin function, but also
     254             :          * an additional @p sysconf keyset with config from system/elektra/plugins to
     255             :          * ensure overrides and disabled variants.
     256             :          *
     257             :          * the function does also add all variants from @p sysconf that were not mentioned
     258             :          * in @p genconf yet.
     259             :          *
     260             :          * @param whichplugin is the plugin for which we want all variants
     261             :          * @param genconf is a keyset containing the genconf config from the plugin
     262             :          * @param sysconf is a keyset containing the system config for system/elektra/plugins
     263             :          *
     264             :          * @return a vector of pluginspecs with variant configurations
     265             :          */
     266             :         std::vector<PluginSpec> getPluginVariantsFromGenconf (PluginSpec const & whichplugin, KeySet const & genconf,
     267             :                                                               KeySet const & sysconf) const;
     268             : 
     269             :         /**
     270             :          * @brief builds a sysconf key from several inputs
     271             :          *
     272             :          * builds a key like:
     273             :          *
     274             :          *   system/elektra/plugin/<whichplugin>/variants/<variant>/<attr>
     275             :          *
     276             :          * @note the function does not add a value and it does not lookup the key in any
     277             :          * keyset, it just creates the key by adding every part as basename.
     278             :          *
     279             :          * @param whichplugin is the plugin for which we want a key
     280             :          * @param variant is the plugin variant for which we want a key
     281             :          * @param attr is the attribute of a variant for which we want a key, e.g. info or config
     282             :          *
     283             :          * @return a newly created key matching the inputs which can be used for lookups for example
     284             :          */
     285             :         Key buildVariantSysconfKey (PluginSpec const & whichplugin, std::string const & variant, const std::string attr) const;
     286             : 
     287             :         /**
     288             :          * @brief adds all keys of a keyset below a certain key to another keyset, rebased
     289             :          *
     290             :          * lets take the input keyset (@p conf):
     291             :          *
     292             :          *   system/elektra/plugins/simpleini/variants/spacesep
     293             :          *   system/elektra/plugins/simpleini/variants/spacesep/config
     294             :          *   system/elektra/plugins/simpleini/variants/spacesep/config/format = % %
     295             :          *   system/elektra/plugins/simpleini/variants/spacesep/config/ignorewhitespace = 1
     296             :          *
     297             :          * and the input key (@p below):
     298             :          *
     299             :          *   system/elektra/plugins/simpleini/variants/spacesep/config
     300             :          *
     301             :          * and the new base key (@p newbase):
     302             :          *
     303             :          *   system/
     304             :          *
     305             :          * then we get the following keys in the output keyset (@p targetconf):
     306             :          *
     307             :          *   system/format = % %
     308             :          *   system/ignorewhitespace = 1
     309             :          *
     310             :          * @param below the parent key for everything we want to add to the target keyset
     311             :          * @param conf the keyset of which we want to add the keys to the target keyset
     312             :          * @param newbase the new base key used in the rebasing process
     313             :          * @param targetconf the target keyset to use for the transformation
     314             :          */
     315             :         void addKeysBelowKeyToConf (Key const & below, KeySet const & conf, Key const & newbase, KeySet & targetconf) const;
     316             : };
     317             : 
     318             : /**
     319             :  * @brief A plugin database that works with added fake data
     320             :  */
     321         328 : class MockPluginDatabase : public ModulesPluginDatabase
     322             : {
     323             : public:
     324             :         typedef int (*checkConfPtr) (ckdb::Key *, ckdb::KeySet *);
     325             : 
     326             :         /// only data from here will be returned
     327             :         /// @note that it is ordered by name, i.e., different ref-names cannot be distinguished
     328             :         mutable std::unordered_map<PluginSpec, std::unordered_map<std::string, std::string>, PluginSpecHash, PluginSpecName> data;
     329             : 
     330             :         std::vector<std::string> listAllPlugins () const;
     331             :         PluginDatabase::Status status (PluginSpec const & whichplugin) const;
     332             :         std::string lookupInfo (PluginSpec const & spec, std::string const & which) const;
     333             :         func_t getSymbol (PluginSpec const & whichplugin, std::string const & which) const;
     334             :         void setCheckconfFunction (checkConfPtr const newCheckconf);
     335             : 
     336             : private:
     337             :         checkConfPtr checkconf = NULL;
     338             : };
     339             : 
     340             : 
     341             : typedef std::shared_ptr<PluginDatabase> PluginDatabasePtr;
     342             : } // namespace tools
     343             : } // namespace kdb
     344             : 
     345             : #endif

Generated by: LCOV version 1.13