Home | History | Annotate | Download | only in parameter
      1 /*
      2  * Copyright (c) 2011-2015, Intel Corporation
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification,
      6  * are permitted provided that the following conditions are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright notice, this
      9  * list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright notice,
     12  * this list of conditions and the following disclaimer in the documentation and/or
     13  * other materials provided with the distribution.
     14  *
     15  * 3. Neither the name of the copyright holder nor the names of its contributors
     16  * may be used to endorse or promote products derived from this software without
     17  * specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 #include <cassert>
     31 #include "ConfigurableDomains.h"
     32 #include "ConfigurableDomain.h"
     33 #include "ConfigurableElement.h"
     34 
     35 #define base CElement
     36 
     37 using std::string;
     38 
     39 string CConfigurableDomains::getKind() const
     40 {
     41     return "ConfigurableDomains";
     42 }
     43 
     44 bool CConfigurableDomains::childrenAreDynamic() const
     45 {
     46     return true;
     47 }
     48 
     49 // Ensure validity on whole domains from main blackboard
     50 void CConfigurableDomains::validate(const CParameterBlackboard *pMainBlackboard)
     51 {
     52     // Delegate to domains
     53     size_t uiNbConfigurableDomains = getNbChildren();
     54 
     55     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
     56 
     57         CConfigurableDomain *pChildConfigurableDomain =
     58             static_cast<CConfigurableDomain *>(getChild(child));
     59 
     60         pChildConfigurableDomain->validate(pMainBlackboard);
     61     }
     62 }
     63 
     64 // Configuration application if required
     65 void CConfigurableDomains::apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet &syncerSet,
     66                                  bool bForce, core::Results &infos) const
     67 {
     68     /// Delegate to domains
     69 
     70     // Start with domains that can be synchronized all at once (with passed syncer set)
     71     size_t uiNbConfigurableDomains = getNbChildren();
     72 
     73     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
     74 
     75         const CConfigurableDomain *pChildConfigurableDomain =
     76             static_cast<const CConfigurableDomain *>(getChild(child));
     77 
     78         std::string info;
     79         // Apply and collect syncers when relevant
     80         pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce, info);
     81 
     82         if (!info.empty()) {
     83             infos.push_back(info);
     84         }
     85     }
     86     // Synchronize those collected syncers
     87     syncerSet.sync(*pParameterBlackboard, false, NULL);
     88 
     89     // Then deal with domains that need to synchronize along apply
     90     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
     91 
     92         const CConfigurableDomain *pChildConfigurableDomain =
     93             static_cast<const CConfigurableDomain *>(getChild(child));
     94 
     95         std::string info;
     96         // Apply and synchronize when relevant
     97         pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce, info);
     98         if (!info.empty()) {
     99             infos.push_back(info);
    100         }
    101     }
    102 }
    103 
    104 // From IXmlSource
    105 void CConfigurableDomains::toXml(CXmlElement &xmlElement,
    106                                  CXmlSerializingContext &serializingContext) const
    107 {
    108     // Set attribute
    109     xmlElement.setAttribute("SystemClassName", getName());
    110 
    111     base::childrenToXml(xmlElement, serializingContext);
    112 }
    113 
    114 // Configuration/Domains handling
    115 /// Domains
    116 bool CConfigurableDomains::createDomain(const string &strName, string &strError)
    117 {
    118     // Already exists?
    119     if (findChild(strName)) {
    120 
    121         strError = "Already existing configurable domain";
    122 
    123         return false;
    124     }
    125 
    126     // Creation/Hierarchy
    127     addChild(new CConfigurableDomain(strName));
    128 
    129     return true;
    130 }
    131 
    132 bool CConfigurableDomains::addDomain(CConfigurableDomain &domain, bool bOverwrite, string &strError)
    133 {
    134     string strErrorDrop;
    135 
    136     string strDomainName(domain.getName());
    137     CConfigurableDomain *pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop);
    138 
    139     if (pExistingDomain) {
    140         if (!bOverwrite) {
    141             strError = "Can't add domain \"" + strDomainName +
    142                        "\" because it already exists and overwrite was not requested.";
    143             return false;
    144         }
    145 
    146         deleteDomain(*pExistingDomain);
    147     }
    148 
    149     addChild(&domain);
    150 
    151     return true;
    152 }
    153 
    154 void CConfigurableDomains::deleteDomain(CConfigurableDomain &configurableDomain)
    155 {
    156     removeChild(&configurableDomain);
    157 
    158     delete &configurableDomain;
    159 }
    160 
    161 bool CConfigurableDomains::deleteDomain(const string &strName, string &strError)
    162 {
    163     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError);
    164 
    165     if (pConfigurableDomain) {
    166         deleteDomain(*pConfigurableDomain);
    167         return true;
    168     }
    169 
    170     return false;
    171 }
    172 
    173 void CConfigurableDomains::deleteAllDomains()
    174 {
    175     // remove Children
    176     clean();
    177 }
    178 
    179 bool CConfigurableDomains::renameDomain(const string &strName, const string &strNewName,
    180                                         string &strError)
    181 {
    182     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError);
    183 
    184     if (!pConfigurableDomain) {
    185 
    186         return false;
    187     }
    188 
    189     // Rename
    190     return pConfigurableDomain->rename(strNewName, strError);
    191 }
    192 
    193 bool CConfigurableDomains::setSequenceAwareness(const string &strDomain, bool bSequenceAware,
    194                                                 string &strError)
    195 {
    196     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    197 
    198     if (!pConfigurableDomain) {
    199 
    200         return false;
    201     }
    202 
    203     pConfigurableDomain->setSequenceAwareness(bSequenceAware);
    204 
    205     return true;
    206 }
    207 
    208 bool CConfigurableDomains::getSequenceAwareness(const string &strDomain, bool &bSequenceAware,
    209                                                 string &strError) const
    210 {
    211     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    212 
    213     if (!pConfigurableDomain) {
    214 
    215         return false;
    216     }
    217 
    218     bSequenceAware = pConfigurableDomain->getSequenceAwareness();
    219 
    220     return true;
    221 }
    222 
    223 /// Configurations
    224 bool CConfigurableDomains::listConfigurations(const string &strDomain, string &strResult) const
    225 {
    226     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    227 
    228     if (!pConfigurableDomain) {
    229 
    230         return false;
    231     }
    232     // delegate
    233     pConfigurableDomain->listChildren(strResult);
    234 
    235     return true;
    236 }
    237 
    238 bool CConfigurableDomains::createConfiguration(const string &strDomain,
    239                                                const string &strConfiguration,
    240                                                const CParameterBlackboard *pMainBlackboard,
    241                                                string &strError)
    242 {
    243     // Find domain
    244     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    245 
    246     if (!pConfigurableDomain) {
    247 
    248         return false;
    249     }
    250     // Delegate
    251     return pConfigurableDomain->createConfiguration(strConfiguration, pMainBlackboard, strError);
    252 }
    253 
    254 bool CConfigurableDomains::deleteConfiguration(const string &strDomain,
    255                                                const string &strConfiguration, string &strError)
    256 {
    257     // Find domain
    258     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    259 
    260     if (!pConfigurableDomain) {
    261 
    262         return false;
    263     }
    264     // Delegate
    265     return pConfigurableDomain->deleteConfiguration(strConfiguration, strError);
    266 }
    267 
    268 bool CConfigurableDomains::renameConfiguration(const string &strDomain,
    269                                                const string &strConfigurationName,
    270                                                const string &strNewConfigurationName,
    271                                                string &strError)
    272 {
    273     // Find domain
    274     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    275 
    276     if (!pConfigurableDomain) {
    277 
    278         return false;
    279     }
    280     // Delegate
    281     return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName,
    282                                                     strError);
    283 }
    284 
    285 bool CConfigurableDomains::listDomainElements(const string &strDomain, string &strResult) const
    286 {
    287     // Find domain
    288     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    289 
    290     if (!pConfigurableDomain) {
    291 
    292         return false;
    293     }
    294     // Delegate
    295     pConfigurableDomain->listAssociatedToElements(strResult);
    296 
    297     return true;
    298 }
    299 
    300 bool CConfigurableDomains::split(const string &domainName, CConfigurableElement *element,
    301                                  core::Results &infos)
    302 {
    303     // Find domain
    304     std::string error;
    305     CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
    306 
    307     if (domain == NULL) {
    308 
    309         infos.push_back(error);
    310         return false;
    311     }
    312     // Delegate
    313     domain->split(element, infos);
    314 
    315     return true;
    316 }
    317 
    318 void CConfigurableDomains::listAssociatedElements(string &strResult) const
    319 {
    320     std::set<const CConfigurableElement *> configurableElementSet;
    321 
    322     // Get all owned configurable elements
    323     gatherAllOwnedConfigurableElements(configurableElementSet);
    324 
    325     // Fill result
    326     std::set<const CConfigurableElement *>::const_iterator it;
    327 
    328     for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
    329 
    330         const CConfigurableElement *pConfigurableElement = *it;
    331 
    332         string strAssociatedDomainList;
    333 
    334         pConfigurableElement->listAssociatedDomains(strAssociatedDomainList, false);
    335 
    336         strResult += pConfigurableElement->getPath() + " [" + strAssociatedDomainList + "]\n";
    337     }
    338 }
    339 
    340 void CConfigurableDomains::listConflictingElements(string &strResult) const
    341 {
    342     std::set<const CConfigurableElement *> configurableElementSet;
    343 
    344     // Get all owned configurable elements
    345     gatherAllOwnedConfigurableElements(configurableElementSet);
    346 
    347     // Fill result
    348     std::set<const CConfigurableElement *>::const_iterator it;
    349 
    350     for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
    351 
    352         const CConfigurableElement *pConfigurableElement = *it;
    353 
    354         if (pConfigurableElement->getBelongingDomainCount() > 1) {
    355 
    356             string strBelongingDomainList;
    357 
    358             pConfigurableElement->listBelongingDomains(strBelongingDomainList, false);
    359 
    360             strResult += pConfigurableElement->getPath() + " contained in multiple domains: " +
    361                          strBelongingDomainList + "\n";
    362         }
    363     }
    364 }
    365 
    366 void CConfigurableDomains::listDomains(string &strResult) const
    367 {
    368     // List domains
    369     size_t uiNbConfigurableDomains = getNbChildren();
    370 
    371     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
    372 
    373         const CConfigurableDomain *pChildConfigurableDomain =
    374             static_cast<const CConfigurableDomain *>(getChild(child));
    375 
    376         // Name
    377         strResult += pChildConfigurableDomain->getName();
    378 
    379         // Sequence awareness
    380         if (pChildConfigurableDomain->getSequenceAwareness()) {
    381 
    382             strResult += " [sequence aware]";
    383         }
    384         strResult += "\n";
    385     }
    386 }
    387 
    388 // Gather configurable elements owned by any domain
    389 void CConfigurableDomains::gatherAllOwnedConfigurableElements(
    390     std::set<const CConfigurableElement *> &configurableElementSet) const
    391 {
    392     // Delegate to domains
    393     size_t uiNbConfigurableDomains = getNbChildren();
    394 
    395     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
    396 
    397         const CConfigurableDomain *pChildConfigurableDomain =
    398             static_cast<const CConfigurableDomain *>(getChild(child));
    399 
    400         pChildConfigurableDomain->gatherConfigurableElements(configurableElementSet);
    401     }
    402 }
    403 
    404 // Config restore
    405 bool CConfigurableDomains::restoreConfiguration(const string &domainName,
    406                                                 const string &configurationName,
    407                                                 CParameterBlackboard *mainBlackboard, bool autoSync,
    408                                                 core::Results &errors) const
    409 {
    410     string error;
    411     // Find domain
    412     const CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
    413 
    414     if (domain == NULL) {
    415 
    416         errors.push_back(error);
    417         return false;
    418     }
    419     // Delegate
    420     return domain->restoreConfiguration(configurationName, mainBlackboard, autoSync, errors);
    421 }
    422 
    423 // Config save
    424 bool CConfigurableDomains::saveConfiguration(const string &strDomain,
    425                                              const string &strConfiguration,
    426                                              const CParameterBlackboard *pMainBlackboard,
    427                                              string &strError)
    428 {
    429     // Find domain
    430     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    431 
    432     if (!pConfigurableDomain) {
    433 
    434         return false;
    435     }
    436     // Delegate
    437     return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError);
    438 }
    439 
    440 bool CConfigurableDomains::setElementSequence(const string &strDomain,
    441                                               const string &strConfiguration,
    442                                               const std::vector<string> &astrNewElementSequence,
    443                                               string &strError)
    444 {
    445     // Find domain
    446     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    447 
    448     if (!pConfigurableDomain) {
    449 
    450         return false;
    451     }
    452 
    453     // Delegate to domain
    454     return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence,
    455                                                    strError);
    456 }
    457 
    458 bool CConfigurableDomains::getElementSequence(const string &strDomain,
    459                                               const string &strConfiguration,
    460                                               string &strResult) const
    461 {
    462     // Find domain
    463     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    464 
    465     if (!pConfigurableDomain) {
    466 
    467         return false;
    468     }
    469     // Delegate to domain
    470     return pConfigurableDomain->getElementSequence(strConfiguration, strResult);
    471 }
    472 
    473 bool CConfigurableDomains::setApplicationRule(
    474     const string &strDomain, const string &strConfiguration, const string &strApplicationRule,
    475     const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError)
    476 {
    477     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    478 
    479     if (!pConfigurableDomain) {
    480 
    481         return false;
    482     }
    483 
    484     // Delegate to domain
    485     return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule,
    486                                                    pSelectionCriteriaDefinition, strError);
    487 }
    488 
    489 bool CConfigurableDomains::clearApplicationRule(const string &strDomain,
    490                                                 const string &strConfiguration, string &strError)
    491 {
    492     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    493 
    494     if (!pConfigurableDomain) {
    495 
    496         return false;
    497     }
    498 
    499     // Delegate to domain
    500     return pConfigurableDomain->clearApplicationRule(strConfiguration, strError);
    501 }
    502 
    503 bool CConfigurableDomains::getApplicationRule(const string &strDomain,
    504                                               const string &strConfiguration,
    505                                               string &strResult) const
    506 {
    507     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    508 
    509     if (!pConfigurableDomain) {
    510 
    511         return false;
    512     }
    513 
    514     // Delegate to domain
    515     return pConfigurableDomain->getApplicationRule(strConfiguration, strResult);
    516 }
    517 
    518 // Last applied configurations
    519 void CConfigurableDomains::listLastAppliedConfigurations(string &strResult) const
    520 {
    521     // Browse domains
    522     size_t uiNbConfigurableDomains = getNbChildren();
    523 
    524     for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
    525 
    526         const CConfigurableDomain *pChildConfigurableDomain =
    527             static_cast<const CConfigurableDomain *>(getChild(child));
    528 
    529         strResult += pChildConfigurableDomain->getName() + ": " +
    530                      pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" +
    531                      pChildConfigurableDomain->getPendingConfigurationName() + "]\n";
    532     }
    533 }
    534 
    535 // Configurable element - domain association
    536 bool CConfigurableDomains::addConfigurableElementToDomain(
    537     const string &domainName, CConfigurableElement *element,
    538     const CParameterBlackboard *mainBlackboard, core::Results &infos)
    539 {
    540     // Find domain
    541     std::string error;
    542     CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
    543 
    544     if (domain == NULL) {
    545 
    546         infos.push_back(error);
    547         return false;
    548     }
    549     // Delegate
    550     return domain->addConfigurableElement(element, mainBlackboard, infos);
    551 }
    552 
    553 bool CConfigurableDomains::removeConfigurableElementFromDomain(
    554     const string &strDomain, CConfigurableElement *pConfigurableElement, string &strError)
    555 {
    556     // Find domain
    557     CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    558 
    559     if (!pConfigurableDomain) {
    560 
    561         return false;
    562     }
    563     // Delegate
    564     return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError);
    565 }
    566 
    567 CParameterBlackboard *CConfigurableDomains::findConfigurationBlackboard(
    568     const string &strDomain, const string &strConfiguration,
    569     const CConfigurableElement *pConfigurableElement, size_t &baseOffset, bool &bIsLastApplied,
    570     string &strError) const
    571 {
    572     // Find domain
    573     const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    574 
    575     if (!pConfigurableDomain) {
    576 
    577         return NULL;
    578     }
    579 
    580     // Check that element belongs to the domain
    581     if (!pConfigurableElement->belongsTo(pConfigurableDomain)) {
    582 
    583         strError = "Element \"" + pConfigurableElement->getPath() +
    584                    "\" does not belong to domain \"" + strDomain + "\"";
    585 
    586         return NULL;
    587     }
    588 
    589     // Find Configuration Blackboard and Base Offset
    590     return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement,
    591                                                             baseOffset, bIsLastApplied, strError);
    592 }
    593 
    594 // Domain retrieval
    595 CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain,
    596                                                                   string &strError)
    597 {
    598     // Call the const equivalent
    599     return const_cast<CConfigurableDomain *>(
    600         static_cast<const CConfigurableDomains *>(this)->findConfigurableDomain(strDomain,
    601                                                                                 strError));
    602 }
    603 
    604 const CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain,
    605                                                                         string &strError) const
    606 {
    607     // Find domain
    608     const CConfigurableDomain *pConfigurableDomain =
    609         static_cast<const CConfigurableDomain *>(findChild(strDomain));
    610 
    611     if (!pConfigurableDomain) {
    612 
    613         strError = "Configurable domain " + strDomain + " not found";
    614 
    615         return NULL;
    616     }
    617 
    618     return pConfigurableDomain;
    619 }
    620