defuze.me  Client
parameterizable.cpp
00001 /**************************************************************************
00002 ** defuze.me Epitech Innovative Project
00003 **
00004 ** Copyright 2010-2011
00005 **   Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard
00006 **   Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier
00007 **
00008 ** All rights reserved.
00009 **************************************************************************/
00010 
00011 #include "parameterizable.hpp"
00012 #include "exception.hpp"
00013 #include "logger.hpp"
00014 #include "paramscore.hpp"
00015 #include "dbcore.hpp"
00016 #include <QtCore/QDebug>
00017 #include <QtCore/QStringList>
00018 #include <QtCore/QSettings>
00019 #include <QtCore/QRegExp>
00020 
00021 using namespace Params;
00022 
00023 Parameterizable::Parameterizable(Parameterizable::BackEnd backEnd, QString name)
00024 {
00025     setParamsBackEnd(backEnd);
00026     setParamsName(name);
00027 }
00028 
00029 void Parameterizable::registerToParamsCore(ParamsCore *paramsCore)
00030 {
00031     if (!hasNameAndBackEnd())
00032         throw_exception(0x01, tr("Missing information about a Parameterizable"));
00033     paramsCore->registerParameterizable(this);
00034     loadDefaultParams();
00035     if (_paramsBackEnd == Parameterizable::SETTINGS)
00036         loadFromSettings();
00037     if (_paramsBackEnd == Parameterizable::DATABASE)
00038         loadFromDatabase();
00039     loadFromCommandLine(paramsCore);
00040     copyParamsToPublic();
00041 }
00042 
00043 bool Parameterizable::setParamsName(const QString &name)
00044 {
00045     _paramsName = name;
00046     return true;
00047 }
00048 
00049 void Parameterizable::setParamsBackEnd(Parameterizable::BackEnd backEnd, DB::DBCore *dbCore)
00050 {
00051     _dbCore = dbCore;
00052     _paramsBackEnd = backEnd;
00053 }
00054 
00055 void Parameterizable::setParamsBackEnd(DB::DBCore *dbCore)
00056 {
00057     setParamsBackEnd(Parameterizable::DATABASE, dbCore);
00058 }
00059 
00060 bool Parameterizable::commitParameters()
00061 {
00062     if (!hasNameAndBackEnd())
00063         throw_exception(0x02, tr("Missing information about a Parameterizable"));
00064     QStringList modifiedKeys;
00065     QHashIterator<QString, QVariant> i(parameters);
00066     while (i.hasNext())
00067     {
00068         i.next();
00069         if ((!publicParameters.contains(i.key())) || publicParameters[i.key()] != i.value())
00070         {
00071             modifiedKeys << i.key();
00072         }
00073     }
00074 
00075     if (_paramsBackEnd == Parameterizable::SETTINGS)
00076     {
00077         QSettings settings;
00078 
00079         settings.beginGroup(_paramsName);
00080         QHash<QString, QVariant>::const_iterator i = parameters.constBegin();
00081         while (i != parameters.constEnd())
00082         {
00083             settings.setValue(i.key(), i.value());
00084             ++i;
00085         }
00086         settings.sync();
00087         settings.endGroup();
00088     }
00089     else if (_paramsBackEnd == Parameterizable::DATABASE)
00090     {
00091         if (!_dbCore)
00092             throw_exception(0x03, tr("DB backend is missing"));
00093         try
00094         {
00095             QHash<QString, QVariant>::const_iterator i = parameters.constBegin();
00096             while (i != parameters.constEnd())
00097             {
00098                 _dbCore->setSetting("params-" + _paramsName + "-" + i.key(), i.value());
00099                 ++i;
00100             }
00101         }
00102         catch (Exception &e)
00103         {
00104             throw_exception(0x04, tr("Cannot commit parameters to the database"));
00105             QHash<QString, QVariant>::const_iterator i = publicParameters.constBegin();
00106             while (i != publicParameters.constEnd())
00107             {
00108                 _dbCore->setSetting("params-" + _paramsName + "-" + i.key(), i.value());
00109                 ++i;
00110             }
00111         }
00112     }
00113 
00114     copyParamsToPublic();
00115     emit commitedValues(modifiedKeys);
00116     return true;
00117 }
00118 
00119 QVariant Parameterizable::getParameter(const QString &key) const
00120 {
00121     if (!parameters.contains(key))
00122         throw_exception(0x05, tr("Undefined parameter: %1").arg(key));
00123     return parameters[key];
00124 }
00125 
00126 QVariant Parameterizable::getParameter(const QString &key, QVariant falloutValue) const
00127 {
00128     if (!parameters.contains(key))
00129         return falloutValue;
00130     return parameters[key];
00131 }
00132 
00133 QVariant Parameterizable::getPublicParameter(const QString &key, QVariant falloutValue) const
00134 {
00135     if (!publicParameters.contains(key))
00136         return falloutValue;
00137     return publicParameters[key];
00138 }
00139 
00140 QVariant Parameterizable::getPublicParameter(const QString &key) const
00141 {
00142     if (!publicParameters.contains(key))
00143         throw_exception(0x06, tr("Undefined public parameter: %1").arg(key));
00144     return publicParameters[key];
00145 }
00146 
00147 void Parameterizable::setParameter(const QString &key, QVariant value)
00148 {
00149     QRegExp keyPattern("[a-z0-9_-]+");
00150 
00151     if (!keyPattern.exactMatch(key))
00152         throw_exception(0x07, tr("Invalid parameter key: %1").arg(key));
00153     parameters[key] = value;
00154 }
00155 
00156 bool Parameterizable::hasNameAndBackEnd() const
00157 {
00158     if (_paramsName.isEmpty() || _paramsBackEnd == UNSET)
00159         return false;
00160     return true;
00161 }
00162 
00163 void Parameterizable::copyParamsToPublic()
00164 {
00165     QHash<QString, QVariant>::const_iterator i = parameters.constBegin();
00166     while (i != parameters.constEnd())
00167     {
00168         publicParameters[i.key()] = i.value();
00169         ++i;
00170     }
00171 }
00172 
00173 const QString& Parameterizable::paramsName() const
00174 {
00175     return _paramsName;
00176 }
00177 
00178 Parameterizable::BackEnd Parameterizable::paramsBackEnd() const
00179 {
00180     return _paramsBackEnd;
00181 }
00182 
00183 void Parameterizable::updatedValues(const QStringList __attribute__((unused)) &keys)
00184 {
00185 
00186 }
00187 
00188 void Parameterizable::applyCmdLineParameters(const QHash<QString, QVariant>& cmdLineParameters)
00189 {
00190     QHash<QString, QVariant>::const_iterator i = cmdLineParameters.constBegin();
00191     while (i != cmdLineParameters.constEnd())
00192     {
00193         setParameter(i.key(), i.value());
00194         ++i;
00195     }
00196 }
00197 
00198 void Parameterizable::loadFromSettings()
00199 {
00200     QSettings settings;
00201 
00202     settings.beginGroup(_paramsName);
00203     QStringList keys = settings.allKeys();
00204     foreach (QString key, keys)
00205     {
00206         setParameter(key, settings.value(key));
00207     }
00208     settings.endGroup();
00209 }
00210 
00211 void Parameterizable::loadDefaultParams()
00212 {
00213     try
00214     {
00215         defineParams();
00216     }
00217     catch (Exception &e)
00218     {
00219         throw_exception(0x08, tr("Cannot load default parameters"));
00220     }
00221 }
00222 
00223 void Parameterizable::loadFromCommandLine(ParamsCore *paramsCore)
00224 {
00225     try
00226     {
00227         applyCmdLineParameters(paramsCore->cmdLineParameters(_paramsName));
00228     }
00229     catch (Exception &e)
00230     {
00231         throw_exception(0x09, tr("Invalid command line parameter"));
00232     }
00233 }
00234 
00235 void Parameterizable::loadFromDatabase()
00236 {
00237     QRegExp rawKeyPattern("params-[a-z_]+-([a-z0-9_-]+)");
00238 
00239     if (!_dbCore)
00240         throw_exception(0x0A, tr("DB backend is missing"));
00241     QHash<QString, QVariant> rawSettings = _dbCore->settingsStartingWith("params-" + _paramsName + "-");
00242     QHash<QString, QVariant>::const_iterator i = rawSettings.constBegin();
00243     while (i != rawSettings.constEnd())
00244     {
00245         QString fullKey = i.key();
00246 
00247         if (rawKeyPattern.exactMatch(fullKey))
00248             setParameter(rawKeyPattern.capturedTexts()[1], i.value());
00249         ++i;
00250     }
00251 }