Home | History | Annotate | Download | only in parameter
      1 /*
      2  * Copyright (c) 2011-2014, 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 #include "BinaryStream.h"
     35 #include "AutoLog.h"
     36 
     37 #define base CBinarySerializableElement
     38 
     39 using std::string;
     40 
     41 CConfigurableDomains::CConfigurableDomains()
     42 {
     43 }
     44 
     45 string CConfigurableDomains::getKind() const
     46 {
     47     return "ConfigurableDomains";
     48 }
     49 
     50 bool CConfigurableDomains::childrenAreDynamic() const
     51 {
     52     return true;
     53 }
     54 
     55 // Ensure validity on whole domains from main blackboard
     56 void CConfigurableDomains::validate(const CParameterBlackboard* pMainBlackboard)
     57 {
     58     // Delegate to domains
     59     size_t uiChild;
     60     size_t uiNbConfigurableDomains = getNbChildren();
     61 
     62     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
     63 
     64         CConfigurableDomain* pChildConfigurableDomain = static_cast<CConfigurableDomain*>(getChild(uiChild));
     65 
     66         pChildConfigurableDomain->validate(pMainBlackboard);
     67     }
     68 }
     69 
     70 // Configuration application if required
     71 void CConfigurableDomains::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet& syncerSet, bool bForce) const
     72 {
     73    CAutoLog autoLog(this, "Applying configurations");
     74 
     75     /// Delegate to domains
     76 
     77     // Start with domains that can be synchronized all at once (with passed syncer set)
     78     size_t uiChild;
     79     size_t uiNbConfigurableDomains = getNbChildren();
     80 
     81     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
     82 
     83         const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild));
     84 
     85         // Apply and collect syncers when relevant
     86         pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce);
     87     }
     88     // Synchronize those collected syncers
     89     syncerSet.sync(*pParameterBlackboard, false, NULL);
     90 
     91     // Then deal with domains that need to synchronize along apply
     92     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
     93 
     94         const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild));
     95 
     96         // Apply and synchronize when relevant
     97         pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce);
     98     }
     99 }
    100 
    101 // From IXmlSource
    102 void CConfigurableDomains::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
    103 {
    104     // Set attribute
    105     xmlElement.setAttributeString("SystemClassName", getName());
    106 
    107     base::childrenToXml(xmlElement, serializingContext);
    108 }
    109 
    110 // Configuration/Domains handling
    111 /// Domains
    112 bool CConfigurableDomains::createDomain(const string& strName, string& strError)
    113 {
    114     // Already exists?
    115     if (findChild(strName)) {
    116 
    117         strError = "Already existing configurable domain";
    118 
    119         return false;
    120     }
    121 
    122     log_info("Creating configurable domain \"%s\"", strName.c_str());
    123 
    124     // Creation/Hierarchy
    125     addChild(new CConfigurableDomain(strName));
    126 
    127     return true;
    128 }
    129 
    130 bool CConfigurableDomains::addDomain(CConfigurableDomain& domain, bool bOverwrite,
    131                                      string& strError)
    132 {
    133     string strErrorDrop;
    134 
    135     string strDomainName(domain.getName());
    136     CConfigurableDomain* pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop);
    137 
    138     if (pExistingDomain) {
    139         if (!bOverwrite) {
    140             strError = "Can't add domain \"" + strDomainName +
    141                 "\" because it already exists and overwrite was not requested.";
    142             return false;
    143         }
    144 
    145         deleteDomain(*pExistingDomain);
    146     }
    147 
    148     log_info("Adding configurable domain \"%s\"", strDomainName.c_str());
    149 
    150     addChild(&domain);
    151 
    152     return true;
    153 }
    154 
    155 void CConfigurableDomains::deleteDomain(CConfigurableDomain& configurableDomain)
    156 {
    157     log_info("Deleting configurable domain \"%s\"", configurableDomain.getName().c_str() );
    158 
    159     removeChild(&configurableDomain);
    160 
    161     delete &configurableDomain;
    162 }
    163 
    164 bool CConfigurableDomains::deleteDomain(const string& strName, string& strError)
    165 {
    166     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError);
    167 
    168     if (pConfigurableDomain) {
    169         deleteDomain(*pConfigurableDomain);
    170         return true;
    171     }
    172 
    173     return false;
    174 }
    175 
    176 void CConfigurableDomains::deleteAllDomains()
    177 {
    178     log_info("Deleting all configurable domains");
    179 
    180     //remove Children
    181     clean();
    182 }
    183 
    184 bool CConfigurableDomains::renameDomain(const string& strName, const string& strNewName, string& strError)
    185 {
    186     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError);
    187 
    188     if (!pConfigurableDomain) {
    189 
    190         return false;
    191     }
    192 
    193     log_info("Renaming configurable domain \"%s\" to \"%s\"", strName.c_str(), strNewName.c_str());
    194 
    195     // Rename
    196     return pConfigurableDomain->rename(strNewName, strError);
    197 }
    198 
    199 bool CConfigurableDomains::setSequenceAwareness(const string& strDomain, bool bSequenceAware, string& strError)
    200 {
    201     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    202 
    203     if (!pConfigurableDomain) {
    204 
    205         return false;
    206     }
    207 
    208     pConfigurableDomain->setSequenceAwareness(bSequenceAware);
    209 
    210     return true;
    211 }
    212 
    213 bool CConfigurableDomains::getSequenceAwareness(const string& strDomain, bool& bSequenceAware, string& strError) const
    214 {
    215     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    216 
    217     if (!pConfigurableDomain) {
    218 
    219         return false;
    220     }
    221 
    222     bSequenceAware = pConfigurableDomain->getSequenceAwareness();
    223 
    224     return true;
    225 }
    226 
    227 /// Configurations
    228 bool CConfigurableDomains::listConfigurations(const string& strDomain, string& strResult) const
    229 {
    230     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    231 
    232     if (!pConfigurableDomain) {
    233 
    234         return false;
    235     }
    236     // delegate
    237     pConfigurableDomain->listChildren(strResult);
    238 
    239     return true;
    240 }
    241 
    242 bool CConfigurableDomains::createConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError)
    243 {
    244     // Find domain
    245     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    246 
    247     if (!pConfigurableDomain) {
    248 
    249         return false;
    250     }
    251     // Delegate
    252     return pConfigurableDomain->createConfiguration(strConfiguration, pMainBlackboard, strError);
    253 }
    254 
    255 bool CConfigurableDomains::deleteConfiguration(const string& strDomain, 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, const string& strConfigurationName, const string& strNewConfigurationName, string& strError)
    269 {
    270     // Find domain
    271     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    272 
    273     if (!pConfigurableDomain) {
    274 
    275         return false;
    276     }
    277     // Delegate
    278     return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName, strError);
    279 }
    280 
    281 bool CConfigurableDomains::listDomainElements(const string& strDomain, string& strResult) const
    282 {
    283     // Find domain
    284     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    285 
    286     if (!pConfigurableDomain) {
    287 
    288         return false;
    289     }
    290     // Delegate
    291     pConfigurableDomain->listAssociatedToElements(strResult);
    292 
    293     return true;
    294 }
    295 
    296 bool CConfigurableDomains::split(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError)
    297 {
    298     // Find domain
    299     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    300 
    301     if (!pConfigurableDomain) {
    302 
    303         return false;
    304     }
    305     // Delegate
    306     pConfigurableDomain->split(pConfigurableElement, strError);
    307 
    308     return true;
    309 }
    310 
    311 void CConfigurableDomains::listAssociatedElements(string& strResult) const
    312 {
    313     strResult = "\n";
    314 
    315     std::set<const CConfigurableElement*> configurableElementSet;
    316 
    317     // Get all owned configurable elements
    318     gatherAllOwnedConfigurableElements(configurableElementSet);
    319 
    320     // Fill result
    321     std::set<const CConfigurableElement*>::const_iterator it;
    322 
    323     for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
    324 
    325         const CConfigurableElement* pConfigurableElement = *it;
    326 
    327         string strAssociatedDomainList;
    328 
    329         pConfigurableElement->listAssociatedDomains(strAssociatedDomainList, false);
    330 
    331         strResult += pConfigurableElement->getPath() + " [" + strAssociatedDomainList + "]\n";
    332     }
    333 }
    334 
    335 void CConfigurableDomains::listConflictingElements(string& strResult) const
    336 {
    337     strResult = "\n";
    338 
    339     std::set<const CConfigurableElement*> configurableElementSet;
    340 
    341     // Get all owned configurable elements
    342     gatherAllOwnedConfigurableElements(configurableElementSet);
    343 
    344     // Fill result
    345     std::set<const CConfigurableElement*>::const_iterator it;
    346 
    347     for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
    348 
    349         const CConfigurableElement* pConfigurableElement = *it;
    350 
    351         if (pConfigurableElement->getBelongingDomainCount() > 1) {
    352 
    353             string strBelongingDomainList;
    354 
    355             pConfigurableElement->listBelongingDomains(strBelongingDomainList, false);
    356 
    357             strResult += pConfigurableElement->getPath() + " contained in multiple domains: " + strBelongingDomainList + "\n";
    358         }
    359     }
    360 }
    361 
    362 void CConfigurableDomains::listDomains(string& strResult) const
    363 {
    364     strResult = "\n";
    365 
    366     // List domains
    367     size_t uiChild;
    368     size_t uiNbConfigurableDomains = getNbChildren();
    369 
    370     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
    371 
    372         const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild));
    373 
    374         // Name
    375         strResult += pChildConfigurableDomain->getName();
    376 
    377         // Sequence awareness
    378         if (pChildConfigurableDomain->getSequenceAwareness()) {
    379 
    380             strResult += " [sequence aware]";
    381         }
    382         strResult += "\n";
    383     }
    384 }
    385 
    386 // Gather configurable elements owned by any domain
    387 void CConfigurableDomains::gatherAllOwnedConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
    388 {
    389     // Delegate to domains
    390     size_t uiChild;
    391     size_t uiNbConfigurableDomains = getNbChildren();
    392 
    393     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
    394 
    395         const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild));
    396 
    397         pChildConfigurableDomain->gatherConfigurableElements(configurableElementSet);
    398     }
    399 }
    400 
    401 // Config restore
    402 bool CConfigurableDomains::restoreConfiguration(const string& strDomain, const string& strConfiguration, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
    403 {
    404     string strError;
    405     // Find domain
    406     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    407 
    408     if (!pConfigurableDomain) {
    409 
    410         lstrError.push_back(strError);
    411         return false;
    412     }
    413     // Delegate
    414     return pConfigurableDomain->restoreConfiguration(strConfiguration, pMainBlackboard, bAutoSync, lstrError);
    415 }
    416 
    417 // Config save
    418 bool CConfigurableDomains::saveConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError)
    419 {
    420     // Find domain
    421     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    422 
    423     if (!pConfigurableDomain) {
    424 
    425         return false;
    426     }
    427     // Delegate
    428     return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError);
    429 }
    430 
    431 bool CConfigurableDomains::setElementSequence(const string& strDomain, const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
    432 {
    433     // Find domain
    434     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    435 
    436     if (!pConfigurableDomain) {
    437 
    438         return false;
    439     }
    440 
    441     // Delegate to domain
    442     return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence, strError);
    443 }
    444 
    445 bool CConfigurableDomains::getElementSequence(const string& strDomain, const string& strConfiguration, string& strResult) const
    446 {
    447     // Find domain
    448     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    449 
    450     if (!pConfigurableDomain) {
    451 
    452         return false;
    453     }
    454     // Delegate to domain
    455     return pConfigurableDomain->getElementSequence(strConfiguration, strResult);
    456 }
    457 
    458 bool CConfigurableDomains::setApplicationRule(const string& strDomain, const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
    459 {
    460     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    461 
    462     if (!pConfigurableDomain) {
    463 
    464         return false;
    465     }
    466 
    467     // Delegate to domain
    468     return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule, pSelectionCriteriaDefinition, strError);
    469 }
    470 
    471 bool CConfigurableDomains::clearApplicationRule(const string& strDomain, const string& strConfiguration, string& strError)
    472 {
    473     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    474 
    475     if (!pConfigurableDomain) {
    476 
    477         return false;
    478     }
    479 
    480     // Delegate to domain
    481     return pConfigurableDomain->clearApplicationRule(strConfiguration, strError);
    482 }
    483 
    484 bool CConfigurableDomains::getApplicationRule(const string& strDomain, const string& strConfiguration, string& strResult) const
    485 {
    486     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
    487 
    488     if (!pConfigurableDomain) {
    489 
    490         return false;
    491     }
    492 
    493     // Delegate to domain
    494     return pConfigurableDomain->getApplicationRule(strConfiguration, strResult);
    495 }
    496 
    497 // Last applied configurations
    498 void CConfigurableDomains::listLastAppliedConfigurations(string& strResult) const
    499 {
    500     // Browse domains
    501     size_t uiChild;
    502     size_t uiNbConfigurableDomains = getNbChildren();
    503 
    504     for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) {
    505 
    506         const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild));
    507 
    508         strResult += pChildConfigurableDomain->getName() + ": " + pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" + pChildConfigurableDomain->getPendingConfigurationName() + "]\n";
    509     }
    510 }
    511 
    512 // Configurable element - domain association
    513 bool CConfigurableDomains::addConfigurableElementToDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
    514 {
    515     // Find domain
    516     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    517 
    518     if (!pConfigurableDomain) {
    519 
    520         return false;
    521     }
    522     // Delegate
    523     return pConfigurableDomain->addConfigurableElement(pConfigurableElement, pMainBlackboard, strError);
    524 }
    525 
    526 bool CConfigurableDomains::removeConfigurableElementFromDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError)
    527 {
    528     // Find domain
    529     CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    530 
    531     if (!pConfigurableDomain) {
    532 
    533         return false;
    534     }
    535     // Delegate
    536     return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError);
    537 }
    538 
    539 CParameterBlackboard* CConfigurableDomains::findConfigurationBlackboard(const string& strDomain,
    540                                                        const string& strConfiguration,
    541                                                        const CConfigurableElement* pConfigurableElement,
    542                                                        uint32_t& uiBaseOffset,
    543                                                        bool& bIsLastApplied,
    544                                                        string& strError) const
    545 {
    546     log_info("Find configuration blackboard for Domain:%s, Configuration:%s, Element:%s",
    547              strDomain.c_str(), strConfiguration.c_str(), pConfigurableElement->getPath().c_str());
    548 
    549     // Find domain
    550     const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);
    551 
    552     if (!pConfigurableDomain) {
    553 
    554         return NULL;
    555     }
    556 
    557     // Check that element belongs to the domain
    558     if (!pConfigurableElement->belongsTo(pConfigurableDomain)) {
    559 
    560         strError = "Element \"" + pConfigurableElement->getPath() + "\" does not belong to domain \"" + strDomain + "\"";
    561 
    562         return NULL;
    563     }
    564 
    565     // Find Configuration Blackboard and Base Offset
    566     return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement, uiBaseOffset, bIsLastApplied, strError);
    567 }
    568 
    569 // Binary settings load/store
    570 bool CConfigurableDomains::serializeSettings(const string& strBinarySettingsFilePath, bool bOut, uint8_t uiStructureChecksum, string& strError)
    571 {
    572     // Instantiate byte stream
    573     CBinaryStream binarySettingsStream(strBinarySettingsFilePath, bOut, getDataSize(), uiStructureChecksum);
    574 
    575     // Open file
    576     if (!binarySettingsStream.open(strError)) {
    577 
    578         strError = "Unable to open binary settings file " + strBinarySettingsFilePath + ": " + strError;
    579 
    580         return false;
    581     }
    582 
    583     // Serialize
    584     binarySerialize(binarySettingsStream);
    585 
    586     // Close stream
    587     binarySettingsStream.close();
    588 
    589     return true;
    590 }
    591 
    592 // Domain retrieval
    593 CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError)
    594 {
    595     // Call the const equivalent
    596     return const_cast<CConfigurableDomain*>(
    597         static_cast<const CConfigurableDomains*>(this)->findConfigurableDomain(strDomain, strError)
    598         );
    599 }
    600 
    601 const CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError) const
    602 {
    603     // Find domain
    604     const CConfigurableDomain* pConfigurableDomain = static_cast<const CConfigurableDomain*>(findChild(strDomain));
    605 
    606     if (!pConfigurableDomain) {
    607 
    608         strError = "Configurable domain " + strDomain + " not found";
    609 
    610         return NULL;
    611     }
    612 
    613     return pConfigurableDomain;
    614 }
    615