Dataquay 0.8
ObjectBuilder.h
Go to the documentation of this file.
1/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3/*
4 Dataquay
5
6 A C++/Qt library for simple RDF datastore management.
7 Copyright 2009-2012 Chris Cannam.
8
9 Permission is hereby granted, free of charge, to any person
10 obtaining a copy of this software and associated documentation
11 files (the "Software"), to deal in the Software without
12 restriction, including without limitation the rights to use, copy,
13 modify, merge, publish, distribute, sublicense, and/or sell copies
14 of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 Except as contained in this notice, the name of Chris Cannam
29 shall not be used in advertising or otherwise to promote the sale,
30 use or other dealings in this Software without prior written
31 authorization.
32*/
33
34#ifndef DATAQUAY_OBJECT_BUILDER_H
35#define DATAQUAY_OBJECT_BUILDER_H
36
37#include <QHash>
38#include <QString>
39#include <QVariant>
40
41namespace Dataquay {
42
64{
65public:
70
84 template <typename T>
86 m_builders[T::staticMetaObject.className()] = new Builder0<T>();
87 }
88
104 template <typename T, typename Parent>
106 m_builders[T::staticMetaObject.className()] = new Builder1<T, Parent>();
107 }
108
126 template <typename T>
127 void registerClass(QString pointerName) {
128 QString className = T::staticMetaObject.className();
129 m_cpmap[className] = pointerName;
130 m_pcmap[pointerName] = className;
131 m_builders[className] = new Builder0<T>();
132 registerExtractor<T>(pointerName);
133 }
134
154 template <typename T, typename Parent>
155 void registerClass(QString pointerName) {
156 QString className = T::staticMetaObject.className();
157 m_cpmap[className] = pointerName;
158 m_pcmap[pointerName] = className;
159 m_builders[className] = new Builder1<T, Parent>();
160 registerExtractor<T>(pointerName);
161 }
162
178 template <typename T>
179 void registerInterface(QString pointerName) {
180 QString className = T::staticMetaObject.className();
181 m_cpmap[className] = pointerName;
182 m_pcmap[pointerName] = className;
183 registerExtractor<T>(pointerName);
184 }
185
190 bool knows(QString className) {
191 return m_builders.contains(className);
192 }
193
199 QObject *build(QString className, QObject *parent) {
200 if (!knows(className)) return 0;
201 return m_builders[className]->build(parent);
202 }
203
208 QObject *build(QString className) {
209 if (!knows(className)) return 0;
210 return m_builders[className]->build(0);
211 }
212
219 bool canExtract(QString pointerName) {
220 return m_extractors.contains(pointerName);
221 }
222
229 bool canInject(QString pointerName) {
230 return m_extractors.contains(pointerName);
231 }
232
239 QObject *extract(QString pointerName, QVariant &v) {
240 if (!canExtract(pointerName)) return 0;
241 return m_extractors[pointerName]->extract(v);
242 }
243
250 QVariant inject(QString pointerName, QObject *p) {
251 if (!canInject(pointerName)) return QVariant();
252 return m_extractors[pointerName]->inject(p);
253 }
254
260 QString getClassNameForPointerName(QString pointerName) const {
261 if (m_pcmap.contains(pointerName)) return m_pcmap[pointerName];
262 return "";
263 }
264
271 QString getPointerNameForClassName(QString className) const {
272 if (m_cpmap.contains(className)) return m_cpmap[className];
273 return "";
274 }
275
276private:
277 ObjectBuilder() {
279 }
280 ~ObjectBuilder() {
281 for (BuilderMap::iterator i = m_builders.begin();
282 i != m_builders.end(); ++i) {
283 delete *i;
284 }
285 for (ExtractorMap::iterator i = m_extractors.begin();
286 i != m_extractors.end(); ++i) {
287 delete *i;
288 }
289 }
290
291 template <typename T>
292 void
293 registerExtractor(QString pointerName) {
294 m_extractors[pointerName] = new Extractor<T *>();
295 }
296
297 template <typename T>
298 void
299 registerExtractor(QString pointerName, QString /* listName */) {
300 m_extractors[pointerName] = new Extractor<T *>();
301 }
302
303 struct BuilderBase {
304 virtual ~BuilderBase() { }
305 virtual QObject *build(QObject *) = 0;
306 };
307
308 template <typename T> struct Builder0 : public BuilderBase {
309 virtual QObject *build(QObject *) {
310 return new T();
311 }
312 };
313
314 template <typename T, typename Parent> struct Builder1 : public BuilderBase {
315 virtual QObject *build(QObject *p) {
316 return new T(qobject_cast<Parent *>(p));
317 }
318 };
319
320 typedef QHash<QString, BuilderBase *> BuilderMap;
321 BuilderMap m_builders;
322
323 struct ExtractorBase {
324 virtual ~ExtractorBase() { }
325 virtual QObject *extract(const QVariant &v) = 0;
326 virtual QVariant inject(QObject *) = 0;
327 };
328
329 template <typename Pointer> struct Extractor : public ExtractorBase {
330 virtual QObject *extract(const QVariant &v) {
331 return v.value<Pointer>();
332 }
333 virtual QVariant inject(QObject *o) {
334 Pointer p = qobject_cast<Pointer>(o);
335 if (p) return QVariant::fromValue<Pointer>(p);
336 else return QVariant();
337 }
338 };
339
340 typedef QHash<QString, ExtractorBase *> ExtractorMap;
341 ExtractorMap m_extractors;
342
343 QHash<QString, QString> m_cpmap;
344 QHash<QString, QString> m_pcmap;
345};
346
347}
348
349#endif
ObjectBuilder is a singleton object factory capable of constructing new objects of classes that are s...
void registerClass()
Register type T, a subclass of QObject, as a class that can be constructed by calling a zero-argument...
void registerClass(QString pointerName)
Register type T, a subclass of QObject, as a class that can be constructed by calling a single-argume...
void registerInterface(QString pointerName)
Register type T, a subclass of QObject, as an interface (a pure virtual class) and pointerName to be ...
bool canInject(QString pointerName)
Return true if the class whose pointer has meta-type name pointerName has been registered with that p...
QString getPointerNameForClassName(QString className) const
If the class whose class name (according to its meta object) is className has been registered using o...
QObject * build(QString className, QObject *parent)
Return a new object whose class name (according to its meta object) is className, with the given pare...
bool canExtract(QString pointerName)
Return true if the class whose pointer has meta-type name pointerName has been registered with that p...
static ObjectBuilder * getInstance()
Retrieve the single global instance of ObjectBuilder.
QString getClassNameForPointerName(QString pointerName) const
Provided the given pointerName has been registered using one of the registerClass(pointerName) method...
void registerClass(QString pointerName)
Register type T, a subclass of QObject, as a class that can be constructed by calling a zero-argument...
bool knows(QString className)
Return true if the class whose class name (according to its meta object) is className has been regist...
QObject * extract(QString pointerName, QVariant &v)
Provided the given pointerName has been registered using one of the registerClass(pointerName) method...
void registerClass()
Register type T, a subclass of QObject, as a class that can be constructed by calling a single-argume...
QVariant inject(QString pointerName, QObject *p)
Provided the given pointerName has been registered using one of the registerClass(pointerName) method...
QObject * build(QString className)
Return a new object whose class name (according to its meta object) is className, constructed with no...