Gaia
layoutawarefactory.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_LAYOUTAWAREFACTORY_H
21 #define GAIA_LAYOUTAWAREFACTORY_H
22 
23 #include <QMap>
24 #include "gaia.h"
25 #include "pointlayout.h"
26 
27 namespace gaia2 {
28 
35 template < typename IdentifierType,
36  typename AbstractProduct,
37  typename LayoutType,
38  typename ArgumentType >
40 
41  protected:
42  typedef AbstractProduct* (*ProductCreator)(const LayoutType&, const ArgumentType&);
43  typedef QMap<IdentifierType, ProductCreator> CreatorMap;
44 
45  CreatorMap _map;
46 
47  public:
48 
49  static LayoutAwareFactory& instance() {
50  static LayoutAwareFactory _instance;
51  return _instance;
52  }
53 
54  static AbstractProduct* create(const IdentifierType& id,
55  const LayoutType& layout,
56  const ArgumentType& arg = ArgumentType()) {
57 
58  AbstractProduct* result;
59  try {
60  result = instance().create_i(id, layout, arg);
61  }
62  catch (FixedLengthException& e) {
63  // add metric name info and re-throw
64  e.msg() = e.msg().arg(id);
65  throw;
66  }
67 
68  result->name = id;
69 
70  // in case user explicitly stated params shouldn't be checked, return the instance now
71  if (result->validParams.size() == 1 && result->validParams[0] == "NO_PARAMS_CHECK") {
72  return result;
73  }
74 
75  // check whether the given parameters are valid before returning the new instance
76  foreach (const QString& p, arg.keys()) {
77  if (!result->validParams.contains(p)) {
78  QStringList msg;
79  msg << "Could not create algorithm " << id << " because parameter " << p
80  << " is not a valid parameter.\n"
81  << "Valid parameters are: " << result->validParams.join(", ");
82  delete result; // clean up the object, as this is a failed initialization
83  throw GaiaException(msg);
84  }
85  }
86 
87  return result;
88  }
89 
90  AbstractProduct* create_i(const IdentifierType& id,
91  const LayoutType& layout,
92  const ArgumentType& arg) const {
93  // slower than just find, but more flexible because case-insensitive (for the factory keys)
94  IdentifierType lid = id.toLower();
95  typename CreatorMap::const_iterator it = _map.constBegin();
96  while (it != _map.constEnd() && it.key().toLower() != lid) {
97  ++it;
98  }
99  if (it == _map.end()) {
100  QStringList msg;
101  msg << "Identifier '" << id << "' not found in registry...\n";
102  msg << "Available keys: " << keys().join(" ");
103  throw GaiaException(msg);
104  }
105 
106  return (*it)(layout, arg);
107  }
108 
109  static QStringList keys() { return instance()._map.keys(); }
110 
111  template <typename ConcreteProduct>
112  class Registrar {
113  public:
114  Registrar(const IdentifierType& id) {
115  LayoutAwareFactory::instance()._map.insert(id, &create);
116  }
117 
118  static AbstractProduct* create(const LayoutType& layout, const ArgumentType& arg) {
119  return new ConcreteProduct(layout, arg);
120  }
121  };
122 
123 };
124 
125 } // namespace gaia2
126 
127 #endif // GAIA_LAYOUTAWAREFACTORY_H
Definition: layoutawarefactory.h:112
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
A tuned implementation of a factory.
Definition: layoutawarefactory.h:39
Exception class that can take up to 3 arguments of any type, which will be serialized into a QString ...
Definition: gaiaexception.h:46