00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "realfactory.h"
00022 #include "configurationnode.h"
00023 #include "configurationparameters.h"
00024 #include "parametersfileloadersaver.h"
00025 #include "parametersettable.h"
00026 #include "configurationexceptions.h"
00027 #include <QFileInfo>
00028 #include <QQueue>
00029 #include <memory>
00030
00031 namespace farsa {
00032
00033 QMap<QString, ConfigurationParameters::FileFormat>& ConfigurationParameters::getFormatsMap()
00034 {
00035 static QMap<QString, ConfigurationParameters::FileFormat> formatsMap;
00036
00037 return formatsMap;
00038 }
00039
00040 QMap<QString, QString>& ConfigurationParameters::getFileExtensionsMap()
00041 {
00042 static QMap<QString, QString> fileExtensionsMap;
00043
00044 return fileExtensionsMap;
00045 }
00046
00047 bool ConfigurationParameters::registerFileFormat(QString format, ParametersFileLoaderSaver *fileLoaderSaver, QString defaultExtension)
00048 {
00049
00050 QMap<QString, FileFormat>::iterator it = getFormatsMap().find(format);
00051 if (it != getFormatsMap().end()) {
00052 return false;
00053 }
00054
00055
00056 if (defaultExtension.isEmpty()) {
00057 defaultExtension = format;
00058 }
00059
00060
00061 FileFormat f(format, fileLoaderSaver, defaultExtension);
00062
00063
00064 getFormatsMap().insert(format, f);
00065 getFileExtensionsMap().insert(defaultExtension, format);
00066
00067 return true;
00068 }
00069
00070 ConfigurationParameters::ConfigurationParameters(bool caseSensitive) :
00071 m_factory(new RealFactory(*this)),
00072 m_root(new ConfigurationNode(NULL, "", caseSensitive)),
00073 m_getObjectFromGroupRecursionLevel(0),
00074 m_objectsToConfigure(),
00075 m_dontForgetGroupObjectAssociations(false),
00076 m_resourcesUserPerRecursionLevel(QList<SimpleResourcesUser>() << SimpleResourcesUser())
00077 {
00078 }
00079
00080 ConfigurationParameters::ConfigurationParameters(const ConfigurationParameters &other) :
00081 m_factory(new RealFactory(*this)),
00082 m_root(NULL),
00083 m_getObjectFromGroupRecursionLevel(0),
00084 m_objectsToConfigure(),
00085 m_dontForgetGroupObjectAssociations(false),
00086 m_resourcesUserPerRecursionLevel(QList<SimpleResourcesUser>() << SimpleResourcesUser())
00087 {
00088
00089 copyTree(other.m_root.get());
00090 }
00091
00092 ConfigurationParameters& ConfigurationParameters::operator=(const ConfigurationParameters &other)
00093 {
00094
00095 if (m_getObjectFromGroupRecursionLevel != 0) {
00096 throw CopyDuringObjectCreationException();
00097 }
00098
00099
00100 if (&other == this) {
00101 return *this;
00102 }
00103
00104
00105 copyTree(other.m_root.get());
00106
00107
00108 m_factory->clearObservers();
00109 m_factory->addObservers(other.m_factory->getObservers());
00110
00111 return *this;
00112 }
00113
00114 ConfigurationParameters::~ConfigurationParameters()
00115 {
00116
00117 }
00118
00119 bool ConfigurationParameters::isCaseSensitive() const
00120 {
00121 return m_root->isCaseSensitive();
00122 }
00123
00124 void ConfigurationParameters::clearAll()
00125 {
00126 m_root->clearAll();
00127 }
00128
00129 QStringList ConfigurationParameters::getGroupsList(QString group) const
00130 {
00131 return m_root->getNode(group)->getChildrenList();
00132 }
00133
00134 QStringList ConfigurationParameters::getGroupsWithPrefixList(QString group, QString prefix) const
00135 {
00136
00137 QRegExp filter(QString("^") + QRegExp::escape(prefix), (isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive));
00138
00139 return getFilteredGroupsList(group, filter);
00140 }
00141
00142 QStringList ConfigurationParameters::getFilteredGroupsList(QString group, QRegExp filter) const
00143 {
00144 return m_root->getNode(group)->getFilteredChildrenList(filter);
00145 }
00146
00147 void ConfigurationParameters::createGroup(QString groupPath)
00148 {
00149
00150 QStringList splittedPath = groupPath.split(ConfigurationParameters::GroupSeparator(), QString::SkipEmptyParts, Qt::CaseSensitive);
00151
00152
00153 ConfigurationNode* lastNode = m_root.get();
00154 for (QStringList::iterator it = splittedPath.begin(); it != splittedPath.end(); it++) {
00155 lastNode = lastNode->addNode(*it);
00156 }
00157 }
00158
00159 bool ConfigurationParameters::deleteGroup(QString groupPath)
00160 {
00161
00162 QString groupName = groupPath.section( ConfigurationParameters::GroupSeparator(), -1 );
00163
00164 QString groupParent = groupPath.section( ConfigurationParameters::GroupSeparator(), 0, -2 );
00165 return m_root->getNode(groupParent)->deleteNode(groupName);
00166 }
00167
00168 bool ConfigurationParameters::renameGroup(QString oldGroupPath, QString newGroupName)
00169 {
00170
00171 QString groupName = oldGroupPath.section( ConfigurationParameters::GroupSeparator(), -1 );
00172
00173 QString groupParent = oldGroupPath.section( ConfigurationParameters::GroupSeparator(), 0, -2 );
00174 return m_root->getNode(groupParent)->renameNode(groupName, newGroupName);
00175 }
00176
00177 void ConfigurationParameters::createParameter(QString groupPath, QString parameter)
00178 {
00179 ConfigurationNode* node = m_root->getNode(groupPath);
00180 if ( !node->isNull() ) {
00181 node->addParameter( parameter );
00182 }
00183 }
00184
00185 void ConfigurationParameters::deleteParameter(QString groupPath, QString parameter) {
00186 ConfigurationNode* node = m_root->getNode(groupPath);
00187 if ( !node->isNull() ) {
00188 node->deleteParameter( parameter );
00189 }
00190 }
00191
00192 bool ConfigurationParameters::startObjectParameters(QString groupPath, QString typeName, ParameterSettable* object)
00193 {
00194
00195 createGroup(groupPath);
00196
00197
00198 createParameter(groupPath, QString("type"), typeName);
00199
00200
00201 return m_root->setObjectForNode(groupPath, object);
00202 }
00203
00204 QString ConfigurationParameters::getValue(QString path, bool alsoMatchParents) const
00205 {
00206 return m_root->getValue(path, alsoMatchParents);
00207 }
00208
00209 bool ConfigurationParameters::setValue(QString path, QString value)
00210 {
00211 return m_root->setValue(path, value);
00212 }
00213
00214 bool ConfigurationParameters::setValue(QString path, ParameterSettable* object)
00215 {
00216 return m_root->setValue(path, object);
00217 }
00218
00219 QStringList ConfigurationParameters::getParametersList(QString group) const
00220 {
00221 return m_root->getNode(group)->getParametersList();
00222 }
00223
00224 QStringList ConfigurationParameters::getParametersWithPrefixList(QString group, QString prefix) const
00225 {
00226
00227 QRegExp filter(QString("^") + QRegExp::escape(prefix), (isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive));
00228
00229 return getFilteredParametersList(group, filter);
00230 }
00231
00232 QStringList ConfigurationParameters::getFilteredParametersList(QString group, QRegExp filter) const
00233 {
00234 return m_root->getNode(group)->getFilteredParametersList(filter);
00235 }
00236
00237 void ConfigurationParameters::startRememberingGroupObjectAssociations()
00238 {
00239 m_dontForgetGroupObjectAssociations = true;
00240 }
00241
00242 void ConfigurationParameters::stopRememberingGroupObjectAssociations()
00243 {
00244 m_dontForgetGroupObjectAssociations = false;
00245 }
00246
00247 void ConfigurationParameters::resetGroupObjectAssociations()
00248 {
00249
00250 QQueue<ConfigurationNode *> nodeQueue;
00251 nodeQueue.enqueue(m_root.get());
00252
00253
00254 while (!nodeQueue.isEmpty()) {
00255
00256 ConfigurationNode *curNode = nodeQueue.dequeue();
00257 curNode->resetObject();
00258
00259
00260 #if QT_VERSION_CHECK > 0x450000
00261 nodeQueue.append(curNode->getChildrenNodesList());
00262 #else
00263 foreach( ConfigurationNode* an, curNode->getChildrenNodesList() ) {
00264 nodeQueue.append( an );
00265 }
00266 #endif
00267 }
00268 }
00269
00270 void ConfigurationParameters::updateObjectReferences()
00271 {
00272
00273
00274
00275
00276 QMap<ParameterSettable *, QString> objectsMap;
00277 QQueue<ConfigurationNode *> nodeQueue;
00278 nodeQueue.enqueue(m_root.get());
00279
00280
00281 while (!nodeQueue.isEmpty()) {
00282
00283 ConfigurationNode *curNode = nodeQueue.dequeue();
00284 ConfigurationNode::ObjectAndStatus object = curNode->getObjectForNode("");
00285
00286 if (object.object != NULL) {
00287
00288
00289
00290
00291
00292
00293 QString fullname = curNode->getFullName();
00294 if ( fullname.startsWith( GroupSeparator() ) ) {
00295 fullname.remove( 0, 1 );
00296 }
00297 objectsMap[object.object] = fullname;
00298 }
00299
00300
00301 #if QT_VERSION_CHECK > 0x450000
00302 nodeQueue.append(curNode->getChildrenNodesList());
00303 #else
00304 foreach( ConfigurationNode* an, curNode->getChildrenNodesList() ) {
00305 nodeQueue.append( an );
00306 }
00307 #endif
00308 }
00309
00310
00311
00312 nodeQueue.enqueue(m_root.get());
00313
00314
00315 while (!nodeQueue.isEmpty()) {
00316
00317 ConfigurationNode *curNode = nodeQueue.dequeue();
00318
00319
00320 QStringList params = curNode->getObjectParametersList();
00321
00322 for (QStringList::iterator it = params.begin(); it != params.end(); it++) {
00323
00324 ParameterSettable *obj = curNode->getObject(*it).object;
00325
00326
00327 if (objectsMap.contains(obj)) {
00328 curNode->setValue(*it, objectsMap[obj]);
00329 } else {
00330 curNode->setValue(*it, QString(""));
00331 }
00332 }
00333
00334
00335 #if QT_VERSION_CHECK > 0x450000
00336 nodeQueue.append(curNode->getChildrenNodesList());
00337 #else
00338 foreach( ConfigurationNode* an, curNode->getChildrenNodesList() ) {
00339 nodeQueue.append( an );
00340 }
00341 #endif
00342 }
00343 }
00344
00345 bool ConfigurationParameters::loadParameters(QString filename, bool keepOld, QString format)
00346 {
00347
00348 if (format.isEmpty()) {
00349 format = formatFromFilenameExtension(filename);
00350
00351 if (format.isNull()) {
00352 return false;
00353 }
00354 }
00355
00356
00357 QMap<QString, FileFormat>::iterator it = getFormatsMap().find(format);
00358
00359
00360 if (it == getFormatsMap().end()) {
00361 return false;
00362 }
00363
00364 return it->fileLoaderSaver->load( filename, *this, keepOld );
00365 }
00366
00367 bool ConfigurationParameters::saveParameters(QString filename, QString format, bool append)
00368 {
00369
00370 updateObjectReferences();
00371
00372
00373 if (format.isEmpty()) {
00374 format = formatFromFilenameExtension(filename);
00375
00376 if (format.isNull()) {
00377 return false;
00378 }
00379 }
00380
00381
00382 QMap<QString, FileFormat>::iterator it = getFormatsMap().find(format);
00383
00384
00385 if (it == getFormatsMap().end()) {
00386 return false;
00387 }
00388
00389 return it->fileLoaderSaver->save( filename, *this, append );
00390 }
00391
00392 SimpleResourcesUser* ConfigurationParameters::getResourcesUserForResource(QString resourceName)
00393 {
00394
00395 for (int i = m_getObjectFromGroupRecursionLevel; i >= 0; i--) {
00396 if (m_resourcesUserPerRecursionLevel[i].hasResource(resourceName)) {
00397 return &(m_resourcesUserPerRecursionLevel[i]);
00398 }
00399 }
00400
00401 return NULL;
00402 }
00403
00404 void ConfigurationParameters::setResourcesUser(ResourcesUser* resourcesUser)
00405 {
00406 m_resourcesUserPerRecursionLevel.last().shareResourcesWith(resourcesUser);
00407 }
00408
00409 void ConfigurationParameters::addObserver(FactoryObserver* observer)
00410 {
00411 m_factory->addObserver(observer);
00412 }
00413
00414 QString ConfigurationParameters::formatFromFilenameExtension(QString filename) const
00415 {
00416 QFileInfo info(filename);
00417
00418 QMap<QString, QString>::const_iterator it = getFileExtensionsMap().find(info.suffix());
00419 if (it == getFileExtensionsMap().end()) {
00420 return QString();
00421 } else {
00422 return *it;
00423 }
00424 }
00425
00426 void ConfigurationParameters::copyTree(const ConfigurationNode *root)
00427 {
00428
00429 m_root.reset(new ConfigurationNode(NULL, root->getName(), root->isCaseSensitive()));
00430
00431
00432 copyNode(root, m_root.get());
00433 }
00434
00435 void ConfigurationParameters::copyNode(const ConfigurationNode *source, ConfigurationNode *target)
00436 {
00437
00438 QStringList params = source->getParametersList();
00439 for (QStringList::const_iterator it = params.begin(); it != params.end(); it++) {
00440 target->addParameter(*it);
00441 target->setValue(*it, source->getValue(*it));
00442 }
00443
00444
00445
00446
00447 QStringList children = source->getChildrenList();
00448 for (QStringList::const_iterator it = children.begin(); it != children.end(); it++) {
00449 target->addNode(*it);
00450 copyNode(source->getNode(*it), target->getNode(*it));
00451 }
00452 }
00453
00454 bool ConfigurationParameters::setObjectFromGroupStatusToCreating(QString group)
00455 {
00456 if (m_getObjectFromGroupRecursionLevel == 0) {
00457 return true;
00458 }
00459 return m_root->setObjectForNode(group, NULL, CreatingObject);
00460 }
00461
00462 bool ConfigurationParameters::setObjectFromGroupStatusToCreatedNotConfigured(QString group, ParameterSettable *object)
00463 {
00464 if (m_getObjectFromGroupRecursionLevel == 0) {
00465 return true;
00466 }
00467 return m_root->setObjectForNode(group, object, ObjectCreatedNotConfigured);
00468 }
00469
00470 bool ConfigurationParameters::setObjectFromGroupStatusToConfiguring(QString group)
00471 {
00472 if (m_getObjectFromGroupRecursionLevel == 0) {
00473 return true;
00474 }
00475 return m_root->setObjectForNode(group, NULL, ConfiguringObject);
00476 }
00477
00478 bool ConfigurationParameters::setObjectFromGroupStatusToCreatingAndConfiguring(QString group)
00479 {
00480 if (m_getObjectFromGroupRecursionLevel == 0) {
00481 return true;
00482 }
00483 return m_root->setObjectForNode(group, NULL, CreatingAndConfiguringObject);
00484 }
00485
00486 bool ConfigurationParameters::setObjectFromGroupStatusToCreatedAndConfigured(QString group, ParameterSettable *object)
00487 {
00488 if (m_getObjectFromGroupRecursionLevel == 0) {
00489 return true;
00490 }
00491 return m_root->setObjectForNode(group, object, ObjectCreatedAndConfigured);
00492 }
00493
00494 }