Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Implements a way to deal with a backend
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 :
11 : #ifndef TOOLS_BACKEND_HPP
12 : #define TOOLS_BACKEND_HPP
13 :
14 : #include <backendparser.hpp>
15 : #include <modules.hpp>
16 : #include <plugin.hpp>
17 : #include <plugins.hpp>
18 : #include <pluginspec.hpp>
19 : #include <toolexcept.hpp>
20 :
21 : #include <deque>
22 : #include <memory>
23 : #include <ostream>
24 : #include <string>
25 : #include <unordered_map>
26 : #include <vector>
27 :
28 : #include <kdb.hpp>
29 :
30 : namespace kdb
31 : {
32 :
33 : namespace tools
34 : {
35 :
36 : /**
37 : * @brief Minimal interface to add plugins
38 : */
39 228 : class BackendInterface
40 : {
41 : public:
42 : virtual void addPlugin (PluginSpec const & spec) = 0;
43 : virtual ~BackendInterface () = 0;
44 : };
45 :
46 : typedef std::unique_ptr<BackendInterface> BackendInterfacePtr;
47 :
48 : /**
49 : * @brief Interface to serialize a backend
50 : */
51 114 : class SerializeInterface
52 : {
53 : public:
54 : virtual void serialize (kdb::KeySet & ret) = 0;
55 : virtual ~SerializeInterface () = 0;
56 : };
57 :
58 : /**
59 : * @brief Interface to work with mountpoints (backends) for factory
60 : */
61 2249 : class MountBackendInterface : public BackendInterface, public SerializeInterface
62 : {
63 : public:
64 : virtual void status (std::ostream & os) const = 0;
65 : virtual bool validated () const = 0;
66 :
67 : virtual void setMountpoint (Key mountpoint, KeySet mountConf) = 0;
68 : virtual std::string getMountpoint () const = 0;
69 :
70 : virtual void setBackendConfig (KeySet const & ks) = 0;
71 :
72 : virtual void useConfigFile (std::string file) = 0;
73 : virtual std::string getConfigFile () const = 0;
74 :
75 : virtual ~MountBackendInterface () = 0;
76 : };
77 :
78 : typedef std::unique_ptr<MountBackendInterface> MountBackendInterfacePtr;
79 :
80 : /**
81 : * @brief A low-level representation of the backend (= set of plugins) that can be mounted.
82 : *
83 : * To build a backend, you should prefer BackendBuilder, which automatically fixes
84 : * ordering and allows us to remove plugins.
85 : */
86 : class Backend : public MountBackendInterface
87 : {
88 : private:
89 : GetPlugins getplugins;
90 : SetPlugins setplugins;
91 : ErrorPlugins errorplugins;
92 :
93 : std::string mp; // empty or valid canonified mountpoint
94 : std::string configFile; // empty or valid configuration file
95 :
96 : Modules modules;
97 : kdb::KeySet config; // the global config, plugins might add something to it
98 :
99 : // make sure plugins get closed before modules
100 : std::vector<PluginPtr> plugins;
101 :
102 :
103 : private:
104 : void tryPlugin (PluginSpec const & spec);
105 :
106 : public:
107 : Backend ();
108 : ~Backend ();
109 :
110 : Backend (Backend const & other) = delete;
111 : Backend & operator= (Backend const & other) = delete;
112 :
113 : Backend (Backend && other);
114 : Backend & operator= (Backend && other);
115 :
116 : void setMountpoint (Key mountpoint, KeySet mountConf);
117 : void setBackendConfig (KeySet const & ks);
118 : void addPlugin (PluginSpec const & spec);
119 : void useConfigFile (std::string file);
120 : void status (std::ostream & os) const;
121 : bool validated () const;
122 : void serialize (kdb::KeySet & ret);
123 :
124 : std::string getMountpoint () const;
125 : std::string getConfigFile () const;
126 : };
127 :
128 : /**
129 : * @brief Factory for MountBackendInterface
130 : */
131 3216 : class BackendFactory
132 : {
133 : std::string which;
134 :
135 : public:
136 844 : explicit BackendFactory (std::string whichBackend) : which (whichBackend)
137 : {
138 : }
139 :
140 : /**
141 : * @brief Create classes that implement MountBackendInterface
142 : */
143 852 : MountBackendInterfacePtr create () const
144 : {
145 1704 : if (which == "backend")
146 : {
147 1704 : return MountBackendInterfacePtr (new Backend ());
148 : }
149 0 : throw NoSuchBackend (which);
150 : }
151 : };
152 :
153 0 : inline std::string Backend::getMountpoint () const
154 : {
155 744 : return mp;
156 : }
157 :
158 0 : inline std::string Backend::getConfigFile () const
159 : {
160 0 : return configFile;
161 : }
162 :
163 : std::ostream & operator<< (std::ostream & os, Backend const & b);
164 :
165 : /**
166 : * @brief Adds plugins in a generic map
167 : */
168 8 : class PluginAdder : public BackendInterface
169 : {
170 : protected:
171 : Modules modules;
172 :
173 : std::unordered_map<std::string, std::deque<std::shared_ptr<Plugin>>> plugins;
174 :
175 : public:
176 : void addPlugin (PluginSpec const & spec);
177 : };
178 :
179 : /**
180 : * @brief Low level representation of global plugins
181 : */
182 4 : class GlobalPlugins : public PluginAdder, public SerializeInterface
183 : {
184 : public:
185 : void serialize (kdb::KeySet & ret);
186 : };
187 :
188 : /**
189 : * @brief Backend for import/export functionality
190 : *
191 : * (only partly implemented)
192 : */
193 0 : class ImportExportBackend : public PluginAdder
194 : {
195 :
196 : public:
197 : ImportExportBackend ()
198 0 : {
199 : }
200 :
201 : void status (std::ostream & os) const;
202 : void importFromFile (KeySet & ks, Key const & parentKey) const;
203 : void exportToFile (KeySet const & ks, Key const & parentKey) const;
204 : };
205 : } // namespace tools
206 : } // namespace kdb
207 :
208 : #endif
|