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 #pragma once
31 
32 #include "BinarySerializableElement.h"
33 #include "XmlSerializingContext.h"
34 #include "XmlDomainImportContext.h"
35 #include "SyncerSet.h"
36 #include <list>
37 #include <set>
38 #include <map>
39 #include <string>
40 
41 class CConfigurableElement;
42 class CDomainConfiguration;
43 class CParameterBlackboard;
44 class CSelectionCriteriaDefinition;
45 
46 class CConfigurableDomain : public CBinarySerializableElement
47 {
48     typedef std::list<CConfigurableElement*>::const_iterator ConfigurableElementListIterator;
49     typedef std::map<const CConfigurableElement*, CSyncerSet*>::const_iterator ConfigurableElementToSyncerSetMapIterator;
50 public:
51     CConfigurableDomain();
52     CConfigurableDomain(const std::string& strName);
53     virtual ~CConfigurableDomain();
54 
55     // Sequence awareness
56     void setSequenceAwareness(bool bSequenceAware);
57     bool getSequenceAwareness() const;
58 
59     // Configuration Management
60     bool createConfiguration(const std::string& strName, const CParameterBlackboard* pMainBlackboard, std::string& strError);
61     bool deleteConfiguration(const std::string& strName, std::string& strError);
62     bool renameConfiguration(const std::string& strName, const std::string& strNewName, std::string& strError);
63     bool restoreConfiguration(const std::string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<std::string>& strError) const;
64     bool saveConfiguration(const std::string& strName, const CParameterBlackboard* pMainBlackboard, std::string& strError);
65     bool setElementSequence(const std::string& strConfiguration, const std::vector<std::string>& astrNewElementSequence, std::string& strError);
66     bool getElementSequence(const std::string& strConfiguration, std::string& strResult) const;
67     bool setApplicationRule(const std::string& strConfiguration, const std::string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, std::string& strError);
68     bool clearApplicationRule(const std::string& strConfiguration, std::string& strError);
69     bool getApplicationRule(const std::string& strConfiguration, std::string& strResult) const;
70 
71     // Last applied configuration name
72     std::string getLastAppliedConfigurationName() const;
73 
74     // Pending configuration name
75     std::string getPendingConfigurationName() const;
76 
77     // Associated Configurable elements
78     void gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const;
79     void listAssociatedToElements(std::string& strResult) const;
80 
81     // Configurable elements association
82     bool addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, std::string& strError);
83     bool removeConfigurableElement(CConfigurableElement* pConfigurableElement, std::string& strError);
84 
85     // Blackboard Configuration and Base Offset retrieval
86     CParameterBlackboard* findConfigurationBlackboard(const std::string& strConfiguration,
87                                                       const CConfigurableElement* pConfigurableElement,
88                                                       uint32_t& uiBaseOffset,
89                                                       bool& bIsLastApplied,
90                                                       std::string& strError) const;
91 
92     // Domain splitting
93     bool split(CConfigurableElement* pConfigurableElement, std::string& strError);
94 
95     // Ensure validity on whole domain from main blackboard
96     void validate(const CParameterBlackboard* pMainBlackboard);
97 
98     // Configuration application if required
99     void apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForced) const;
100 
101     // Return applicable configuration validity for given configurable element
102     bool isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const;
103 
104     // From IXmlSink
105     virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
106 
107     // From IXmlSource
108     virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const;
109     virtual void childrenToXml(CXmlElement& xmlElement,
110                                CXmlSerializingContext& serializingContext) const;
111 
112     // Class kind
113     virtual std::string getKind() const;
114 
115 protected:
116     // Content dumping
117     virtual void logValue(std::string& strValue, CErrorContext& errorContext) const;
118 
119 private:
120     // Get pending configuration
121     const CDomainConfiguration* getPendingConfiguration() const;
122 
123     // Search for an applicable configuration
124     const CDomainConfiguration* findApplicableDomainConfiguration() const;
125 
126     // Returns true if children dynamic creation is to be dealt with (here, will allow child deletion upon clean)
127     virtual bool childrenAreDynamic() const;
128 
129     // Ensure validity on areas related to configurable element
130     void validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard);
131 
132     // Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
133     void autoValidateAll();
134 
135     // Attempt validation for one configurable element's areas, relying on already existing valid configuration inside domain
136     void autoValidateAreas(const CConfigurableElement* pConfigurableElement);
137 
138     // Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
139     bool autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration);
140 
141     // Search for a valid configuration for given configurable element
142     const CDomainConfiguration* findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const;
143 
144 
145     // In case configurable element was removed
146     void computeSyncSet();
147 
148     // Check configurable element already attached
149     bool containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const;
150 
151     // Merge any descended configurable element to this one
152     void mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement);
153     void mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement);
154 
155     // Configurable elements association
156     void doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard = NULL);
157     void doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet);
158 
159     // XML parsing
160     /**
161      * Deserialize domain configurations from an Xml document and add them to
162      * the domain.
163      *
164      * @param[in] xmlElement the XML element to be parsed
165      * @param[in] serializingContext context for the deserialization
166      *
167      * @return false if an error occurs, true otherwise.
168      */
169     bool parseDomainConfigurations(const CXmlElement& xmlElement,
170                                    CXmlDomainImportContext& serializingContext);
171     /**
172      * Deserialize domain elements from an Xml document and add them to
173      * the domain.
174      *
175      * @param[in] xmlElement the XML element to be parsed
176      * @param[in] serializingContext context for the deserialization
177      *
178      * @return false if an error occurs, true otherwise.
179      */
180     bool parseConfigurableElements(const CXmlElement& xmlElement,
181                                    CXmlDomainImportContext& serializingContext);
182     /**
183      * Deserialize settings from an Xml document and add them to
184      * the domain.
185      *
186      * @param[in] xmlElement the XML element to be parsed
187      * @param[in] xmlDomainImportContext context for the deserialization
188      *
189      * @return false if an error occurs, true otherwise.
190      */
191     bool parseSettings(const CXmlElement& xmlElement,
192                        CXmlDomainImportContext& serializingContext);
193 
194     // XML composing
195     void composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const;
196     void composeConfigurableElements(CXmlElement& xmlElement) const;
197     void composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const;
198 
199     // Syncer set retrieval from configurable element
200     CSyncerSet* getSyncerSet(const CConfigurableElement* pConfigurableElement) const;
201 
202     // Configuration retrieval
203     CDomainConfiguration* findConfiguration(const std::string& strConfiguration, std::string& strError);
204     const CDomainConfiguration* findConfiguration(const std::string& strConfiguration, std::string& strError) const;
205 
206     // Configurable elements
207     std::list<CConfigurableElement*> _configurableElementList;
208 
209     // Associated syncer sets
210     std::map<const CConfigurableElement*, CSyncerSet*> _configurableElementToSyncerSetMap;
211 
212     // Sequence awareness
213     bool _bSequenceAware;
214 
215     // Syncer set used to ensure propoer synchronization of restored configurable elements
216     CSyncerSet _syncerSet;
217 
218     // Last applied configuration
219     mutable const CDomainConfiguration* _pLastAppliedConfiguration;
220 };
221 
222