Gaia
factory.h
1 /*
2  * Copyright (C) 2006-2013 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Gaia
5  *
6  * Gaia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef GAIA_FACTORY_H
21 #define GAIA_FACTORY_H
22 
23 #include <QMap>
24 #include "gaia.h"
25 
26 namespace gaia2 {
27 
38 template < typename IdentifierType,
39  typename AbstractProduct,
40  typename ArgumentType >
41 class Factory {
42 
43  protected:
44  typedef AbstractProduct* (*ProductCreator)(const ArgumentType&);
45  typedef QMap<IdentifierType, ProductCreator> CreatorMap;
46 
47  CreatorMap _map;
48 
49  public:
50 
51  static Factory& instance() {
52  static Factory _instance;
53  return _instance;
54  }
55 
56  static AbstractProduct* create(const IdentifierType& id,
57  const ArgumentType& arg = ArgumentType()) {
58  return instance().create_i(id, arg);
59  }
60 
61  AbstractProduct* create_i(const IdentifierType& id, const ArgumentType& arg) const {
62  // slower than just find, but more flexible because case-insensitive (for the factory keys)
63  IdentifierType lid = id.toLower();
64  typename CreatorMap::const_iterator it = _map.constBegin();
65  while (it != _map.constEnd() && it.key().toLower() != lid) {
66  ++it;
67  }
68  if (it == _map.constEnd()) {
69  QStringList msg;
70  msg << "Identifier '" << id << "' not found in registry...\n";
71  msg << "Available keys: " << keys().join(" ");
72  throw GaiaException(msg);
73  }
74 
75  return (*it)(arg);
76  }
77 
78  static QStringList keys() { return instance()._map.keys(); }
79 
80  template <typename ConcreteProduct>
81  class Registrar {
82  public:
83  Registrar(const IdentifierType& id) {
84  Factory::instance()._map.insert(id, &create);
85  }
86 
87  static AbstractProduct* create(const ArgumentType& arg) {
88  return new ConcreteProduct(arg);
89  }
90  };
91 
92 };
93 
94 
95 template < typename IdentifierType,
96  typename AbstractProduct,
97  typename ArgumentType >
98 class ParamCheckingFactory : public Factory<IdentifierType, AbstractProduct, ArgumentType> {
99 
100  public:
102 
103  static ParamCheckingFactory& instance() {
104  return static_cast<ParamCheckingFactory&>(BaseFactory::instance());
105  }
106 
107  static AbstractProduct* create(const IdentifierType& id,
108  const ArgumentType& arg = ArgumentType()) {
109 
110  AbstractProduct* result;
111  try {
112  result = BaseFactory::instance().create_i(id, arg);
113  }
114  catch (FixedLengthException& e) {
115  e.msg() = e.msg().arg(id);
116  throw;
117  }
118  catch (GaiaException& e) {
119  QStringList msg;
120  msg << "Could not instantiate " << id << " analyzer because: " << e.msg();
121  throw GaiaException(msg);
122  }
123 
124  result->name = id;
125 
126  // check whether the given parameters are valid before returning the new instance
127  foreach (const QString& p, arg.keys()) {
128  if (!result->validParams.contains(p)) {
129  QStringList msg;
130  msg << "Could not create algorithm " << id << " because parameter " << p
131  << " is not a valid parameter.\n"
132  << "Valid parameters are: " << result->validParams.join(", ");
133  delete result; // clean up the object, as this is a failed initialization
134  throw GaiaException(msg);
135  }
136  }
137 
138  return result;
139  }
140 
141 };
142 
143 
144 
145 } // namespace gaia2
146 
147 #endif // GAIA_FACTORY_H
A basic implementation of a generic factory class.
Definition: factory.h:41
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
Definition: factory.h:98
Definition: factory.h:81
Exception class that can take up to 3 arguments of any type, which will be serialized into a QString ...
Definition: gaiaexception.h:46