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
getKind() const39 string CConfigurableDomains::getKind() const
40 {
41 return "ConfigurableDomains";
42 }
43
childrenAreDynamic() const44 bool CConfigurableDomains::childrenAreDynamic() const
45 {
46 return true;
47 }
48
49 // Ensure validity on whole domains from main blackboard
validate(const CParameterBlackboard * pMainBlackboard)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
apply(CParameterBlackboard * pParameterBlackboard,CSyncerSet & syncerSet,bool bForce,core::Results & infos) const65 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, nullptr);
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, nullptr, bForce, info);
98 if (!info.empty()) {
99 infos.push_back(info);
100 }
101 }
102 }
103
104 // From IXmlSource
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const105 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
createDomain(const string & strName,string & strError)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
addDomain(CConfigurableDomain & domain,bool bOverwrite,string & strError)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
deleteDomain(CConfigurableDomain & configurableDomain)154 void CConfigurableDomains::deleteDomain(CConfigurableDomain &configurableDomain)
155 {
156 removeChild(&configurableDomain);
157
158 delete &configurableDomain;
159 }
160
deleteDomain(const string & strName,string & strError)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
deleteAllDomains()173 void CConfigurableDomains::deleteAllDomains()
174 {
175 // remove Children
176 clean();
177 }
178
renameDomain(const string & strName,const string & strNewName,string & strError)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
setSequenceAwareness(const string & strDomain,bool bSequenceAware,string & strError)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
getSequenceAwareness(const string & strDomain,bool & bSequenceAware,string & strError) const208 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
listConfigurations(const string & strDomain,string & strResult) const224 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
createConfiguration(const string & strDomain,const string & strConfiguration,const CParameterBlackboard * pMainBlackboard,string & strError)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
deleteConfiguration(const string & strDomain,const string & strConfiguration,string & strError)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
renameConfiguration(const string & strDomain,const string & strConfigurationName,const string & strNewConfigurationName,string & strError)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
listDomainElements(const string & strDomain,string & strResult) const285 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
split(const string & domainName,CConfigurableElement * element,core::Results & infos)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 == nullptr) {
308
309 infos.push_back(error);
310 return false;
311 }
312 // Delegate
313 domain->split(element, infos);
314
315 return true;
316 }
317
listAssociatedElements(string & strResult) const318 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
listConflictingElements(string & strResult) const340 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
listDomains(string & strResult) const366 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
gatherAllOwnedConfigurableElements(std::set<const CConfigurableElement * > & configurableElementSet) const389 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
restoreConfiguration(const string & domainName,const string & configurationName,CParameterBlackboard * mainBlackboard,bool autoSync,core::Results & errors) const405 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 == nullptr) {
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
saveConfiguration(const string & strDomain,const string & strConfiguration,const CParameterBlackboard * pMainBlackboard,string & strError)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
setElementSequence(const string & strDomain,const string & strConfiguration,const std::vector<string> & astrNewElementSequence,string & strError)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
getElementSequence(const string & strDomain,const string & strConfiguration,string & strResult) const458 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
setApplicationRule(const string & strDomain,const string & strConfiguration,const string & strApplicationRule,const CSelectionCriteriaDefinition * pSelectionCriteriaDefinition,string & strError)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
clearApplicationRule(const string & strDomain,const string & strConfiguration,string & strError)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
getApplicationRule(const string & strDomain,const string & strConfiguration,string & strResult) const503 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
listLastAppliedConfigurations(string & strResult) const519 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
addConfigurableElementToDomain(const string & domainName,CConfigurableElement * element,const CParameterBlackboard * mainBlackboard,core::Results & infos)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 == nullptr) {
545
546 infos.push_back(error);
547 return false;
548 }
549 // Delegate
550 return domain->addConfigurableElement(element, mainBlackboard, infos);
551 }
552
removeConfigurableElementFromDomain(const string & strDomain,CConfigurableElement * pConfigurableElement,string & strError)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
findConfigurationBlackboard(const string & strDomain,const string & strConfiguration,const CConfigurableElement * pConfigurableElement,size_t & baseOffset,bool & bIsLastApplied,string & strError) const567 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 nullptr;
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 nullptr;
587 }
588
589 // Find Configuration Blackboard and Base Offset
590 return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement,
591 baseOffset, bIsLastApplied, strError);
592 }
593
594 // Domain retrieval
findConfigurableDomain(const string & strDomain,string & strError)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
findConfigurableDomain(const string & strDomain,string & strError) const604 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 nullptr;
616 }
617
618 return pConfigurableDomain;
619 }
620