/*
* Copyright (c) 2011-2015, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "XmlSerializingContext.h"
#include "XmlDomainImportContext.h"
#include "XmlDomainExportContext.h"
#include "SyncerSet.h"
#include "Results.h"
#include <list>
#include <set>
#include <map>
#include <string>
class CConfigurableElement;
class CDomainConfiguration;
class CParameterBlackboard;
class CSelectionCriteriaDefinition;
class CConfigurableDomain : public CElement
{
typedef std::list<CConfigurableElement *>::const_iterator ConfigurableElementListIterator;
typedef std::map<const CConfigurableElement *, CSyncerSet *>::const_iterator
ConfigurableElementToSyncerSetMapIterator;
public:
CConfigurableDomain() = default;
CConfigurableDomain(const std::string &strName);
virtual ~CConfigurableDomain();
// Sequence awareness
void setSequenceAwareness(bool bSequenceAware);
bool getSequenceAwareness() const;
// Configuration Management
bool createConfiguration(const std::string &strName,
const CParameterBlackboard *pMainBlackboard, std::string &strError);
bool deleteConfiguration(const std::string &strName, std::string &strError);
bool renameConfiguration(const std::string &strName, const std::string &strNewName,
std::string &strError);
/** Restore a configuration
*
* @param[in] configurationName the configuration name
* @param[in] mainBlackboard the application main blackboard
* @param[in] autoSync boolean which indicates if auto sync mechanism is on
* @param[out] errors, errors encountered during restoration
* @return true if success false otherwise
*/
bool restoreConfiguration(const std::string &configurationName,
CParameterBlackboard *mainBlackboard, bool autoSync,
core::Results &errors) const;
bool saveConfiguration(const std::string &strName, const CParameterBlackboard *pMainBlackboard,
std::string &strError);
bool setElementSequence(const std::string &strConfiguration,
const std::vector<std::string> &astrNewElementSequence,
std::string &strError);
bool getElementSequence(const std::string &strConfiguration, std::string &strResult) const;
bool setApplicationRule(const std::string &strConfiguration,
const std::string &strApplicationRule,
const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition,
std::string &strError);
bool clearApplicationRule(const std::string &strConfiguration, std::string &strError);
bool getApplicationRule(const std::string &strConfiguration, std::string &strResult) const;
// Last applied configuration name
std::string getLastAppliedConfigurationName() const;
// Pending configuration name
std::string getPendingConfigurationName() const;
// Associated Configurable elements
void gatherConfigurableElements(
std::set<const CConfigurableElement *> &configurableElementSet) const;
void listAssociatedToElements(std::string &strResult) const;
/** Add a configurable element to the domain
*
* @param[in] pConfigurableElement pointer to the element to add
* @param[in] pMainBlackboard pointer to the application main blackboard
* @param[out] infos useful information we can provide to client
* @return true if succeed false otherwise
*/
bool addConfigurableElement(CConfigurableElement *pConfigurableElement,
const CParameterBlackboard *pMainBlackboard, core::Results &infos);
bool removeConfigurableElement(CConfigurableElement *pConfigurableElement,
std::string &strError);
// Blackboard Configuration and Base Offset retrieval
CParameterBlackboard *findConfigurationBlackboard(
const std::string &strConfiguration, const CConfigurableElement *pConfigurableElement,
size_t &baseOffset, bool &bIsLastApplied, std::string &strError) const;
/** Split the domain in two.
* Remove an element of a domain and create a new domain which owns the element.
*
* @param[in] pConfigurableElement pointer to the element to remove
* @param[out] infos useful information we can provide to client
* @return true if succeed false otherwise
*/
bool split(CConfigurableElement *pConfigurableElement, core::Results &infos);
// Ensure validity on whole domain from main blackboard
void validate(const CParameterBlackboard *pMainBlackboard);
/** Apply the configuration if required
*
* @param[in] pParameterBlackboard the blackboard to synchronize
* @param[in] pSyncerSet pointer to the set containing application syncers
* @param[in] bForced boolean used to force configuration application
* @param[out] info string containing useful information we can provide to client
*/
void apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet *pSyncerSet, bool bForced,
std::string &info) const;
// Return applicable configuration validity for given configurable element
bool isApplicableConfigurationValid(const CConfigurableElement *pConfigurableElement) const;
// From IXmlSink
virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext);
// From IXmlSource
virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const;
virtual void childrenToXml(CXmlElement &xmlElement,
CXmlSerializingContext &serializingContext) const;
// Class kind
virtual std::string getKind() const;
protected:
// Content dumping
std::string logValue(utility::ErrorContext &errorContext) const override;
private:
// Get pending configuration
const CDomainConfiguration *getPendingConfiguration() const;
// Search for an applicable configuration
const CDomainConfiguration *findApplicableDomainConfiguration() const;
// Returns true if children dynamic creation is to be dealt with (here, will allow child
// deletion upon clean)
virtual bool childrenAreDynamic() const;
// Ensure validity on areas related to configurable element
void validateAreas(const CConfigurableElement *pConfigurableElement,
const CParameterBlackboard *pMainBlackboard);
// Attempt validation for all configurable element's areas, relying on already existing valid
// configuration inside domain
void autoValidateAll();
// Attempt validation for one configurable element's areas, relying on already existing valid
// configuration inside domain
void autoValidateAreas(const CConfigurableElement *pConfigurableElement);
// Attempt configuration validation for all configurable elements' areas, relying on already
// existing valid configuration inside domain
bool autoValidateConfiguration(CDomainConfiguration *pDomainConfiguration);
// Search for a valid configuration for given configurable element
const CDomainConfiguration *findValidDomainConfiguration(
const CConfigurableElement *pConfigurableElement) const;
// In case configurable element was removed
void computeSyncSet();
// Check configurable element already attached
bool containsConfigurableElement(
const CConfigurableElement *pConfigurableCandidateElement) const;
/** Merge any descended configurable element to this one
*
* @param[in] newElement pointer to element which has potential descendants which can be merged
* @param[out] infos useful information we can provide to client
*/
void mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement *newElement,
core::Results &infos);
void mergeConfigurations(CConfigurableElement *pToConfigurableElement,
CConfigurableElement *pFromConfigurableElement);
/** Actually realize the association between the domain and a configurable element
*
* @param[in] pConfigurableElement pointer to the element to add
* @param[out] infos useful information we can provide to client
* @param[in] (optional) pMainBlackboard, pointer to the application main blackboard
* Default value is NULL, when provided, blackboard area concerning the configurable
* element are validated.
*/
void doAddConfigurableElement(CConfigurableElement *pConfigurableElement, core::Results &infos,
const CParameterBlackboard *pMainBlackboard = NULL);
void doRemoveConfigurableElement(CConfigurableElement *pConfigurableElement,
bool bRecomputeSyncSet);
// XML parsing
/**
* Deserialize domain configurations from an Xml document and add them to
* the domain.
*
* @param[in] xmlElement the XML element to be parsed
* @param[in] serializingContext context for the deserialization
*
* @return false if an error occurs, true otherwise.
*/
bool parseDomainConfigurations(const CXmlElement &xmlElement,
CXmlDomainImportContext &serializingContext);
/**
* Deserialize domain elements from an Xml document and add them to
* the domain.
*
* @param[in] xmlElement the XML element to be parsed
* @param[in] serializingContext context for the deserialization
*
* @return false if an error occurs, true otherwise.
*/
bool parseConfigurableElements(const CXmlElement &xmlElement,
CXmlDomainImportContext &serializingContext);
/**
* Deserialize settings from an Xml document and add them to
* the domain.
*
* @param[in] xmlElement the XML element to be parsed
* @param[in] xmlDomainImportContext context for the deserialization
*
* @return false if an error occurs, true otherwise.
*/
bool parseSettings(const CXmlElement &xmlElement, CXmlDomainImportContext &serializingContext);
// XML composing
void composeDomainConfigurations(CXmlElement &xmlElement,
CXmlSerializingContext &serializingContext) const;
void composeConfigurableElements(CXmlElement &xmlElement) const;
void composeSettings(CXmlElement &xmlElement, CXmlDomainExportContext &context) const;
// Syncer set retrieval from configurable element
CSyncerSet *getSyncerSet(const CConfigurableElement *pConfigurableElement) const;
// Configuration retrieval
CDomainConfiguration *findConfiguration(const std::string &strConfiguration,
std::string &strError);
const CDomainConfiguration *findConfiguration(const std::string &strConfiguration,
std::string &strError) const;
// Configurable elements
std::list<CConfigurableElement *> _configurableElementList;
// Associated syncer sets
std::map<const CConfigurableElement *, CSyncerSet *> _configurableElementToSyncerSetMap;
// Sequence awareness
bool _bSequenceAware{false};
// Syncer set used to ensure propoer synchronization of restored configurable elements
CSyncerSet _syncerSet;
// Last applied configuration
mutable const CDomainConfiguration *_pLastAppliedConfiguration{nullptr};
};