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