blob: 807171f5f76f711e3f9da4a79b78088a446a47b6 [file] [log] [blame]
Patrick Benavoli68a91282011-08-31 11:23:23 +02001/* <auto_header>
2 * <FILENAME>
3 *
4 * INTEL CONFIDENTIAL
5 * Copyright © 2011 Intel
6 * Corporation All Rights Reserved.
7 *
8 * The source code contained or described herein and all documents related to
9 * the source code ("Material") are owned by Intel Corporation or its suppliers
10 * or licensors. Title to the Material remains with Intel Corporation or its
11 * suppliers and licensors. The Material contains trade secrets and proprietary
12 * and confidential information of Intel or its suppliers and licensors. The
13 * Material is protected by worldwide copyright and trade secret laws and
14 * treaty provisions. No part of the Material may be used, copied, reproduced,
15 * modified, published, uploaded, posted, transmitted, distributed, or
16 * disclosed in any way without Intel’s prior express written permission.
17 *
18 * No license under any patent, copyright, trade secret or other intellectual
19 * property right is granted to or conferred upon you by disclosure or delivery
20 * of the Materials, either expressly, by implication, inducement, estoppel or
21 * otherwise. Any license under such intellectual property rights must be
22 * express and approved by Intel in writing.
23 *
24 * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com)
25 * CREATED: 2011-06-01
26 * UPDATED: 2011-07-27
27 *
28 *
29 * </auto_header>
30 */
31#include "ConfigurableDomain.h"
32#include "DomainConfiguration.h"
33#include "ConfigurableElement.h"
34#include "ConfigurationAccessContext.h"
35#include "Subsystem.h"
36#include "XmlDomainSerializingContext.h"
37#include <assert.h>
38
39#define base CBinarySerializableElement
40
41CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _pLastAppliedConfiguration(NULL)
42{
43}
44
45CConfigurableDomain::~CConfigurableDomain()
46{
47 ConfigurableElementListIterator it;
48
49 // Browse all configurable elements for their syncers
50 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
51
52 CConfigurableElement* pConfigurableElement = *it;
53
54 // Remove from configurable element
55 pConfigurableElement->removeAttachedConfigurableDomain(this);
56 }
57}
58
59string CConfigurableDomain::getKind() const
60{
61 return "ConfigurableDomain";
62}
63
64bool CConfigurableDomain::childrenAreDynamic() const
65{
66 return true;
67}
68
69// From IXmlSource
70void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
71{
72 // Configurations
73 composeDomainConfigurations(xmlElement, serializingContext);
74
75 // Configurable Elements
76 composeConfigurableElements(xmlElement, serializingContext);
77}
78
79// XML composing
80void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
81{
82 // Create Configurations element
83 CXmlElement xmlConfigurationsElement;
84
85 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
86
87 // Delegate to base
88 base::toXml(xmlConfigurationsElement, serializingContext);
89}
90
91void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
92{
93 // Context
94 const CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<const CXmlDomainSerializingContext&>(serializingContext);
95
96 // Create ConfigurableElements element
97 CXmlElement xmlConfigurableElementsElement;
98
99 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
100
101 // Serialize out all configurable elements settings
102 ConfigurableElementListIterator it;
103
104 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
105
106 const CConfigurableElement* pConfigurableElement = *it;
107
108 // Create corresponding XML child element
109 CXmlElement xmlChildConfigurableElement;
110
111 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
112
113 // Set Path attribute
114 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
115
116 if (xmlDomainSerializingContext.withSettings()) {
117
118 // Compose configurations for that configurable element
119 composeConfigurableElementConfigurations(pConfigurableElement, xmlChildConfigurableElement, serializingContext);
120 }
121 }
122}
123
124// Serialize configurations for one configurable element
125void CConfigurableDomain::composeConfigurableElementConfigurations(const CConfigurableElement* pConfigurableElement, CXmlElement& xmlConfigurableElementElement, CXmlSerializingContext& serializingContext) const
126{
127 uint32_t uiNbConfigurations = getNbChildren();
128 uint32_t uiChildConfiguration;
129
130 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
131
132 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
133
134 // Create child xml element for that configuration
135 CXmlElement xmlConfigurationSettingsElement;
136
137 xmlConfigurableElementElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
138
139 // Set its name attribute
140 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
141
142 // Have domain configuration serialize settings for configurable element
143 ((CConfigurableDomain&)(*this)).serializeConfigurableElementConfiguration((CDomainConfiguration*)pDomainConfiguration, pConfigurableElement, xmlConfigurationSettingsElement, serializingContext, true);
144 }
145}
146
147// From IXmlSink
148bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
149{
150 // Local parsing. Do not dig
151 return parseDomainConfigurations(xmlElement, serializingContext) && parseConfigurableElements(xmlElement, serializingContext);
152}
153
154// XML parsing
155bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
156{
157 // We're supposedly clean
158 assert(_configurableElementList.empty());
159
160 // Get Configurations element
161 CXmlElement xmlConfigurationsElement;
162
163 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
164
165 // Parse it and create domain configuration objects
166 return base::fromXml(xmlConfigurationsElement, serializingContext);
167}
168
169// Parse configurable elements
170bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
171{
172 // Context
173 const CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<const CXmlDomainSerializingContext&>(serializingContext);
174
175 // Get System Class Element
176 CElement* pRootElement = getRoot();
177
178 CElement* pSystemClassElement = pRootElement->findChildOfKind("SystemClass");
179
180 assert(pSystemClassElement);
181
182 // Get ConfigurableElements element
183 CXmlElement xmlConfigurableElementsElement;
184 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
185
186 // Parse it and associate found configurable elements to it
187 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
188
189 CXmlElement xmlConfigurableElementElement;
190
191 while (it.next(xmlConfigurableElementElement)) {
192
193 // Locate configurable element
194 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
195
196 CPathNavigator pathNavigator(strConfigurableElementPath);
197
198 string* pStrChildName = pathNavigator.next();
199
200 // Is there an element and does it match system class name?
201 if (!pStrChildName || *pStrChildName != pSystemClassElement->getName()) {
202
203 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
204
205 return false;
206 }
207
208 // Browse system class for configurable element
209 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pSystemClassElement->findDescendant(pathNavigator));
210
211 if (!pConfigurableElement) {
212
213 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
214
215 return false;
216 }
217 // Add found element to domain
218 string strError;
219 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
220
221 serializingContext.setError(strError);
222
223 return false;
224 }
225
226 // Check we need to parse configuration settings
227 if (xmlDomainSerializingContext.withSettings()) {
228
229 // Make Domain configuration parse associated configuration nodes if any
230 if (!parseConfigurableElementConfigurations(pConfigurableElement, xmlConfigurableElementElement, serializingContext)) {
231
232 return false;
233 }
234 }
235 }
236 // All provided configurations are parsed
237 // Attempt validation on areas of non provided configurations for all configurable elements
238 autoValidateAll();
239
240 return true;
241}
242
243// Parse configurations for one configurable element
244bool CConfigurableDomain::parseConfigurableElementConfigurations(const CConfigurableElement* pConfigurableElement, CXmlElement& xmlConfigurableElementElement, CXmlSerializingContext& serializingContext)
245{
246 // Context
247 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
248
249 // Parse configurable element's configuration settings
250 CXmlElement::CChildIterator it(xmlConfigurableElementElement);
251
252 CXmlElement xmlConfigurationSettingsElement;
253
254 while (it.next(xmlConfigurationSettingsElement)) {
255 // Get domain configuration
256 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
257
258 if (!pDomainConfiguration) {
259
260 xmlDomainSerializingContext.setError("Could not find domain configuration referred to by configurable element of path " + xmlConfigurableElementElement.getPath() + " from ConfigurableDomain description " + getName());
261
262 return false;
263 }
264 // Have domain configuration parse settings for configurable element
265 if (!serializeConfigurableElementConfiguration(pDomainConfiguration, pConfigurableElement, xmlConfigurationSettingsElement, xmlDomainSerializingContext, false)) {
266
267 return false;
268 }
269 }
270
271 return true;
272}
273
274// Serialize one configuration for one configurable element
275bool CConfigurableDomain::serializeConfigurableElementConfiguration(CDomainConfiguration* pDomainConfiguration, const CConfigurableElement* pConfigurableElement, CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext, bool bSerializeOut)
276{
277 // Actual XML context
278 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
279
280 // Change context type for parameter settings access
281 string strError;
282
283 // Create configuration access context
284 CConfigurationAccessContext configurationAccessContext(strError, bSerializeOut);
285
286 // Provide current value space
287 configurationAccessContext.setValueSpaceRaw(xmlDomainSerializingContext.valueSpaceIsRaw());
288
289 // Get subsystem
290 const CSubsystem* pSubsystem = pConfigurableElement->getBelongingSubsystem();
291
292 if (pSubsystem && pSubsystem != pConfigurableElement) {
293
294 // Element is a descendant of subsystem
295
296 // Deal with Endianness
297 configurationAccessContext.setBigEndianSubsystem(pSubsystem->isBigEndian());
298 }
299
300 // Have domain configuration parse settings for configurable element
301 if (!pDomainConfiguration->serializeXmlSettings(pConfigurableElement, xmlConfigurationSettingsElement, configurationAccessContext)) {
302
303 // Forward error
304 xmlDomainSerializingContext.setError(strError);
305
306 return false;
307 }
308 return true;
309}
310
311// Configurable elements association
312bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
313{
314 // Already associated?
315 if (containsConfigurableElement(pConfigurableElement)) {
316
317 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
318
319 return false;
320 }
321
322 // Already owned?
323 if (pConfigurableElement->belongsTo(this)) {
324
325 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
326
327 return false;
328 }
329 log("Adding configurable element \"%s\" into domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
330
331 // Do add
332 doAddConfigurableElement(pConfigurableElement);
333
334 // Ensure area validity for that configurable element (if main blackboard provided)
335 if (pMainBlackboard) {
336
337 // Need to validate against main blackboard
338 validateAreas(pConfigurableElement, pMainBlackboard);
339 }
340
341 return true;
342}
343
344bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
345{
346 // Not associated?
347 if (!containsConfigurableElement(pConfigurableElement)) {
348
349 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
350
351 return false;
352 }
353 log("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
354
355 // Do remove
356 doRemoveConfigurableElement(pConfigurableElement, true);
357
358 return true;
359}
360
361// Domain splitting
362bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
363{
364 // Not associated?
365 if (!containsConfigurableElement(pConfigurableElement)) {
366
367 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
368
369 return false;
370 }
371 log("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
372
373 // Create sub domain areas for all configurable element's children
374 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
375
376 if (!uiNbConfigurableElementChildren) {
377
378 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
379
380 return false;
381 }
382
383 uint32_t uiChild;
384
385 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
386
387 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
388
389 doAddConfigurableElement(pChildConfigurableElement);
390 }
391
392 // Delegate to configurations
393 uint32_t uiNbConfigurations = getNbChildren();
394
395 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
396
397 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
398
399 pDomainConfiguration->split(pConfigurableElement);
400 }
401
402 // Remove given configurable element from this domain
403 // Note: we shouldn't need to recompute the sync set in that case, as the splitted element should include the syncers of its children elements
404 doRemoveConfigurableElement(pConfigurableElement, false);
405
406 return true;
407}
408
409// Configuration application if required
410void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet& syncerSet, bool bForce)
411{
412 if (bForce) {
413 // Force a configuration restore by forgetting about last applied configuration
414 _pLastAppliedConfiguration = NULL;
415 }
416 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
417
418 if (pApplicableDomainConfiguration) {
419
420 // Check not the last one before applying
421 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
422
423 log("Applying configuration \"%s\" from domain \"%s\"", pApplicableDomainConfiguration->getName().c_str(), getName().c_str());
424
425 // Do the restore
426 pApplicableDomainConfiguration->restore(pParameterBlackboard);
427
428 // Record last applied configuration
429 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
430
431 // Since we applied changes, add our own sync set to the given one
432 syncerSet += _syncerSet;
433 }
434 }
435}
436
437// Return applicable configuration validity for given configurable element
438bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
439{
440 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
441
442 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
443}
444
445// Presence of application condition on any configuration
446bool CConfigurableDomain::hasRules() const
447{
448 // Delegate to configurations
449 uint32_t uiNbConfigurations = getNbChildren();
450 uint32_t uiChild;
451
452 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
453
454 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
455
456 if (pDomainConfiguration->hasRule()) {
457
458 return true;
459 }
460 }
461 return false;
462}
463
464// In case configurable element was removed
465void CConfigurableDomain::computeSyncSet()
466{
467 // Clean sync set first
468 _syncerSet.clear();
469
470 // Browse all configurable elements for their syncers
471 ConfigurableElementListIterator it;
472
473 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
474
475 const CConfigurableElement* pConfigurableElement = *it;
476
477 pConfigurableElement->fillSyncerSet(_syncerSet);
478 }
479}
480
481// Configuration Management
482bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
483{
484 // Already exists?
485 if (findChild(strName)) {
486
487 strError = "Already existing configuration";
488
489 return false;
490 }
491 log("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
492
493 // Creation
494 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
495
496 // Configurable elements association
497 ConfigurableElementListIterator it;
498
499 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
500
501 pDomainConfiguration->addConfigurableElement(*it);
502 }
503
504 // Hierarchy
505 addChild(pDomainConfiguration);
506
507 // Ensure validity of fresh new domain configuration
508 // Attempt auto validation, so that the user gets his/her own settings by defaults
509 if (!autoValidateConfiguration(pDomainConfiguration)) {
510
511 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
512 pDomainConfiguration->validate(pMainBlackboard);
513 }
514
515 return true;
516}
517
518bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
519{
520 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strName));
521
522 if (!pDomainConfiguration) {
523
524 strError = "Configuration not found";
525
526 return false;
527 }
528
529 // Check configuration has no rule (prevent accidental loss of data)
530 if (pDomainConfiguration->hasRule()) {
531
532 strError = "Deletion of configuration containing application rules is not supported to prevent any accitental loss of data.\nPlease consider a direct modification of the XML file.";
533
534 return false;
535 }
536
537 log("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
538
539 // Was the last applied?
540 if (pDomainConfiguration == _pLastAppliedConfiguration) {
541
542 // Forget about it
543 _pLastAppliedConfiguration = NULL;
544 }
545
546 // Hierarchy
547 removeChild(pDomainConfiguration);
548
549 // Destroy
550 delete pDomainConfiguration;
551
552 return true;
553}
554
555void CConfigurableDomain::listAssociatedToElements(string& strResult) const
556{
557 strResult = "\n";
558
559 ConfigurableElementListIterator it;
560
561 // Browse all configurable elements
562 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
563
564 const CConfigurableElement* pConfigurableElement = *it;
565
566 strResult += pConfigurableElement->getPath() + "\n";
567 }
568}
569
570bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
571{
572 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strName));
573
574 if (!pDomainConfiguration) {
575
576 strError = "Configuration not found";
577
578 return false;
579 }
580 log("Renaming domain \"%s\"'s configuration \"%s\" to \"%s\"", getName().c_str(), strName.c_str(), strNewName.c_str());
581
582 // Rename
583 return pDomainConfiguration->rename(strNewName, strError);
584}
585
586bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, string& strError)
587{
588 // Find Domain configuration
589 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strName));
590
591 if (!pDomainConfiguration) {
592
593 strError = "Domain configuration " + strName + " not found";
594
595 return false;
596 }
597 log("Restoring domain \"%s\"'s configuration \"%s\" to parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str());
598
599 // Delegate
600 pDomainConfiguration->restore(pMainBlackboard);
601
602 // Record last applied configuration
603 _pLastAppliedConfiguration = pDomainConfiguration;
604
605 // Synchronize
606 return !bAutoSync || _syncerSet.sync(*pMainBlackboard, false, strError);
607}
608
609bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
610{
611 // Find Domain configuration
612 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strName));
613
614 if (!pDomainConfiguration) {
615
616 strError = "Domain configuration " + strName + " not found";
617
618 return false;
619 }
620 log("Saving domain \"%s\"'s configuration \"%s\" from parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str());
621
622 // Delegate
623 pDomainConfiguration->save(pMainBlackboard);
624
625 return true;
626}
627
628// Last applied configuration
629string CConfigurableDomain::getLastAppliedConfigurationName() const
630{
631 if (_pLastAppliedConfiguration) {
632
633 return _pLastAppliedConfiguration->getName();
634 }
635 return "<none>";
636}
637
638// Ensure validity on whole domain from main blackboard
639void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
640{
641 log("Validating whole domain \"" + getName() + "\" against main blackboard");
642
643 // Propagate
644 uint32_t uiNbConfigurations = getNbChildren();
645 uint32_t uiChild;
646
647 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
648
649 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
650
651 pDomainConfiguration->validate(pMainBlackboard);
652 }
653}
654
655// Ensure validity on areas related to configurable element
656void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
657{
658 log("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
659
660 // Propagate
661 uint32_t uiNbConfigurations = getNbChildren();
662 uint32_t uiChild;
663
664 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
665
666 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
667
668 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
669 }
670}
671
672// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
673void CConfigurableDomain::autoValidateAll()
674{
675 // Validate
676 ConfigurableElementListIterator it;
677
678 // Browse all configurable elements for configuration validation
679 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
680
681 const CConfigurableElement* pConfigurableElement = *it;
682
683 // Auto validate element
684 autoValidateAreas(pConfigurableElement);
685 }
686}
687
688// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
689void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
690{
691 // Find first valid configuration for given configurable element
692 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
693
694 // No valid configuration found, give up
695 if (!pValidDomainConfiguration) {
696
697 return;
698 }
699
700 log("Auto validating domain \"" + getName() + "\" against configuration \"" + pValidDomainConfiguration->getName() + "\" for configurable element " + pConfigurableElement->getPath());
701
702 // Validate all other configurations against found one, if any
703 uint32_t uiNbConfigurations = getNbChildren();
704 uint32_t uiChild;
705
706 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
707
708 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
709
710 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
711 // Validate
712 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
713 }
714 }
715}
716
717// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
718bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
719{
720 // Find another configuration than this one, that ought to be valid!
721 uint32_t uiNbConfigurations = getNbChildren();
722 uint32_t uiChild;
723
724 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
725
726 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
727
728 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
729
730 // Validate against it
731 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
732
733 return true;
734 }
735 }
736 return false;
737}
738#if 0
739void CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
740{
741 // Validate
742 ConfigurableElementListIterator it;
743
744 // Browse all configurable elements for configuration validation
745 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
746
747 const CConfigurableElement* pConfigurableElement = *it;
748
749 // Find first valid configuration for given configurable element
750 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
751
752 // Check valid configuration exists for that configurable element
753 if (pValidDomainConfiguration) {
754
755 // Called on purpose
756 assert(pValidDomainConfiguration != pDomainConfiguration);
757
758 // Validate
759 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
760 }
761 }
762}
763#endif
764// Search for a valid configuration for given configurable element
765const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
766{
767 uint32_t uiNbConfigurations = getNbChildren();
768 uint32_t uiChild;
769
770 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
771
772 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
773
774 if (pDomainConfiguration->isValid(pConfigurableElement)) {
775
776 return pDomainConfiguration;
777 }
778 }
779 return NULL;
780}
781
782// Search for an applicable configuration
783const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
784{
785 uint32_t uiNbConfigurations = getNbChildren();
786 uint32_t uiChild;
787
788 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
789
790 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
791
792 if (pDomainConfiguration->isApplicable()) {
793
794 return pDomainConfiguration;
795 }
796 }
797 return NULL;
798}
799
800// Gather set of configurable elements
801void CConfigurableDomain::gatherConfigurableElements(set<const CConfigurableElement*>& configurableElementSet) const
802{
803 // Insert all configurable elements
804 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
805}
806
807// Check configurable element already attached
808bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
809{
810 ConfigurableElementListIterator it;
811
812 // Browse all configurable elements for comparison
813 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
814
815 if (pConfigurableCandidateElement == *it) {
816
817 return true;
818 }
819 }
820 return false;
821}
822
823// Merge any descended configurable element to this one with this one
824void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
825{
826 list<CConfigurableElement*> mergedConfigurableElementList;
827
828 ConfigurableElementListIterator it;
829
830 // Browse all configurable elements (new one not yet in the list!)
831 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
832
833 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
834
835 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
836
837 log("In domain \"%s\", merging descendant configurable element's configurations \"%s\" into its ascendant \"%s\" ones", getName().c_str(), pConfigurablePotentialDescendantElement->getName().c_str(), pNewConfigurableElement->getName().c_str());
838
839 // Merge configuration data
840 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
841
842 // Keep track for removal
843 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
844 }
845 }
846
847 // Remove all merged elements (new one not yet in the list!)
848 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
849
850 CConfigurableElement* pMergedConfigurableElement = *it;
851
852 // Remove merged from configurable element from internal tracking list
853 // Note: we shouldn't need to recompute the sync set in that case, as the merged to element should include the syncers of merged from elements
854 doRemoveConfigurableElement(pMergedConfigurableElement, false);
855 }
856}
857
858void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
859{
860 // Propagate to domain configurations
861 uint32_t uiNbConfigurations = getNbChildren();
862 uint32_t uiChild;
863
864 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
865
866 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
867
868 // Do the merge.
869 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
870 }
871}
872
873// Configurable elements association
874void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement)
875{
876 // Inform configurable element
877 pConfigurableElement->addAttachedConfigurableDomain(this);
878
879 // Inform configurations
880 uint32_t uiNbConfigurations = getNbChildren();
881 uint32_t uiChild;
882
883 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
884
885 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
886
887 pDomainConfiguration->addConfigurableElement(pConfigurableElement);
888 }
889 // Add to our own sync set the configurable element one
890 pConfigurableElement->fillSyncerSet(_syncerSet);
891
892 // Already associated descended configurable elements need a merge of their configuration data
893 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
894
895 // Add to list
896 _configurableElementList.push_back(pConfigurableElement);
897}
898
899void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
900{
901 // Remove from list
902 _configurableElementList.remove(pConfigurableElement);
903
904 // Inform configurable element
905 pConfigurableElement->removeAttachedConfigurableDomain(this);
906
907 // Inform configurations
908 uint32_t uiNbConfigurations = getNbChildren();
909 uint32_t uiChild;
910
911 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
912
913 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
914
915 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
916 }
917 // Recompute our sync set if needed
918 if (bRecomputeSyncSet) {
919
920 computeSyncSet();
921 }
922}