xref: /aosp_15_r20/external/parameter-framework/upstream/parameter/DomainConfiguration.cpp (revision c33452fb792a5495ec310a9626f2638b053af5dd)
1*c33452fbSAndroid Build Coastguard Worker /*
2*c33452fbSAndroid Build Coastguard Worker  * Copyright (c) 2011-2015, Intel Corporation
3*c33452fbSAndroid Build Coastguard Worker  * All rights reserved.
4*c33452fbSAndroid Build Coastguard Worker  *
5*c33452fbSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without modification,
6*c33452fbSAndroid Build Coastguard Worker  * are permitted provided that the following conditions are met:
7*c33452fbSAndroid Build Coastguard Worker  *
8*c33452fbSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright notice, this
9*c33452fbSAndroid Build Coastguard Worker  * list of conditions and the following disclaimer.
10*c33452fbSAndroid Build Coastguard Worker  *
11*c33452fbSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*c33452fbSAndroid Build Coastguard Worker  * this list of conditions and the following disclaimer in the documentation and/or
13*c33452fbSAndroid Build Coastguard Worker  * other materials provided with the distribution.
14*c33452fbSAndroid Build Coastguard Worker  *
15*c33452fbSAndroid Build Coastguard Worker  * 3. Neither the name of the copyright holder nor the names of its contributors
16*c33452fbSAndroid Build Coastguard Worker  * may be used to endorse or promote products derived from this software without
17*c33452fbSAndroid Build Coastguard Worker  * specific prior written permission.
18*c33452fbSAndroid Build Coastguard Worker  *
19*c33452fbSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20*c33452fbSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21*c33452fbSAndroid Build Coastguard Worker  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22*c33452fbSAndroid Build Coastguard Worker  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23*c33452fbSAndroid Build Coastguard Worker  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*c33452fbSAndroid Build Coastguard Worker  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26*c33452fbSAndroid Build Coastguard Worker  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28*c33452fbSAndroid Build Coastguard Worker  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*c33452fbSAndroid Build Coastguard Worker  */
30*c33452fbSAndroid Build Coastguard Worker #include "DomainConfiguration.h"
31*c33452fbSAndroid Build Coastguard Worker #include "ConfigurableElement.h"
32*c33452fbSAndroid Build Coastguard Worker #include "CompoundRule.h"
33*c33452fbSAndroid Build Coastguard Worker #include "Subsystem.h"
34*c33452fbSAndroid Build Coastguard Worker #include "XmlDomainSerializingContext.h"
35*c33452fbSAndroid Build Coastguard Worker #include "XmlDomainImportContext.h"
36*c33452fbSAndroid Build Coastguard Worker #include "XmlDomainExportContext.h"
37*c33452fbSAndroid Build Coastguard Worker #include "ConfigurationAccessContext.h"
38*c33452fbSAndroid Build Coastguard Worker #include "AlwaysAssert.hpp"
39*c33452fbSAndroid Build Coastguard Worker #include <assert.h>
40*c33452fbSAndroid Build Coastguard Worker #include <cstdlib>
41*c33452fbSAndroid Build Coastguard Worker #include <algorithm>
42*c33452fbSAndroid Build Coastguard Worker #include <numeric>
43*c33452fbSAndroid Build Coastguard Worker #include "RuleParser.h"
44*c33452fbSAndroid Build Coastguard Worker 
45*c33452fbSAndroid Build Coastguard Worker #define base CElement
46*c33452fbSAndroid Build Coastguard Worker 
47*c33452fbSAndroid Build Coastguard Worker using std::string;
48*c33452fbSAndroid Build Coastguard Worker 
CDomainConfiguration(const string & strName)49*c33452fbSAndroid Build Coastguard Worker CDomainConfiguration::CDomainConfiguration(const string &strName) : base(strName)
50*c33452fbSAndroid Build Coastguard Worker {
51*c33452fbSAndroid Build Coastguard Worker }
52*c33452fbSAndroid Build Coastguard Worker 
53*c33452fbSAndroid Build Coastguard Worker // Class kind
getKind() const54*c33452fbSAndroid Build Coastguard Worker string CDomainConfiguration::getKind() const
55*c33452fbSAndroid Build Coastguard Worker {
56*c33452fbSAndroid Build Coastguard Worker     return "Configuration";
57*c33452fbSAndroid Build Coastguard Worker }
58*c33452fbSAndroid Build Coastguard Worker 
59*c33452fbSAndroid Build Coastguard Worker // Child dynamic creation
childrenAreDynamic() const60*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::childrenAreDynamic() const
61*c33452fbSAndroid Build Coastguard Worker {
62*c33452fbSAndroid Build Coastguard Worker     return true;
63*c33452fbSAndroid Build Coastguard Worker }
64*c33452fbSAndroid Build Coastguard Worker 
65*c33452fbSAndroid Build Coastguard Worker // XML configuration settings parsing
parseSettings(CXmlElement & xmlConfigurationSettingsElement,CXmlDomainImportContext & context)66*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::parseSettings(CXmlElement &xmlConfigurationSettingsElement,
67*c33452fbSAndroid Build Coastguard Worker                                          CXmlDomainImportContext &context)
68*c33452fbSAndroid Build Coastguard Worker {
69*c33452fbSAndroid Build Coastguard Worker     // Parse configurable element's configuration settings
70*c33452fbSAndroid Build Coastguard Worker     CXmlElement::CChildIterator it(xmlConfigurationSettingsElement);
71*c33452fbSAndroid Build Coastguard Worker 
72*c33452fbSAndroid Build Coastguard Worker     CXmlElement xmlConfigurableElementSettingsElement;
73*c33452fbSAndroid Build Coastguard Worker     auto insertLocation = begin(mAreaConfigurationList);
74*c33452fbSAndroid Build Coastguard Worker 
75*c33452fbSAndroid Build Coastguard Worker     while (it.next(xmlConfigurableElementSettingsElement)) {
76*c33452fbSAndroid Build Coastguard Worker 
77*c33452fbSAndroid Build Coastguard Worker         // Retrieve area configuration
78*c33452fbSAndroid Build Coastguard Worker         string configurableElementPath;
79*c33452fbSAndroid Build Coastguard Worker         xmlConfigurableElementSettingsElement.getAttribute("Path", configurableElementPath);
80*c33452fbSAndroid Build Coastguard Worker 
81*c33452fbSAndroid Build Coastguard Worker         auto areaConfiguration = findAreaConfigurationByPath(configurableElementPath);
82*c33452fbSAndroid Build Coastguard Worker         if (areaConfiguration == end(mAreaConfigurationList)) {
83*c33452fbSAndroid Build Coastguard Worker 
84*c33452fbSAndroid Build Coastguard Worker             context.setError("Configurable Element " + configurableElementPath +
85*c33452fbSAndroid Build Coastguard Worker                              " referred to by Configuration " + getPath() +
86*c33452fbSAndroid Build Coastguard Worker                              " not associated to Domain");
87*c33452fbSAndroid Build Coastguard Worker 
88*c33452fbSAndroid Build Coastguard Worker             return false;
89*c33452fbSAndroid Build Coastguard Worker         }
90*c33452fbSAndroid Build Coastguard Worker         // Parse
91*c33452fbSAndroid Build Coastguard Worker         if (!importOneConfigurableElementSettings(areaConfiguration->get(),
92*c33452fbSAndroid Build Coastguard Worker                                                   xmlConfigurableElementSettingsElement, context)) {
93*c33452fbSAndroid Build Coastguard Worker 
94*c33452fbSAndroid Build Coastguard Worker             return false;
95*c33452fbSAndroid Build Coastguard Worker         }
96*c33452fbSAndroid Build Coastguard Worker         // Take into account the new configuration order by moving the configuration associated to
97*c33452fbSAndroid Build Coastguard Worker         // the element to the n-th position of the configuration list.
98*c33452fbSAndroid Build Coastguard Worker         // It will result in prepending to the configuration list wit the configuration of all
99*c33452fbSAndroid Build Coastguard Worker         // elements found in XML, keeping the order of the processing of the XML file.
100*c33452fbSAndroid Build Coastguard Worker         mAreaConfigurationList.splice(insertLocation, mAreaConfigurationList, areaConfiguration);
101*c33452fbSAndroid Build Coastguard Worker         // areaConfiguration is still valid, but now refer to the reorderer list
102*c33452fbSAndroid Build Coastguard Worker         insertLocation = std::next(areaConfiguration);
103*c33452fbSAndroid Build Coastguard Worker     }
104*c33452fbSAndroid Build Coastguard Worker     return true;
105*c33452fbSAndroid Build Coastguard Worker }
106*c33452fbSAndroid Build Coastguard Worker 
107*c33452fbSAndroid Build Coastguard Worker // XML configuration settings composing
composeSettings(CXmlElement & xmlConfigurationSettingsElement,CXmlDomainExportContext & context) const108*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::composeSettings(CXmlElement &xmlConfigurationSettingsElement,
109*c33452fbSAndroid Build Coastguard Worker                                            CXmlDomainExportContext &context) const
110*c33452fbSAndroid Build Coastguard Worker {
111*c33452fbSAndroid Build Coastguard Worker     // Go through all are configurations
112*c33452fbSAndroid Build Coastguard Worker     for (auto &areaConfiguration : mAreaConfigurationList) {
113*c33452fbSAndroid Build Coastguard Worker 
114*c33452fbSAndroid Build Coastguard Worker         // Retrieve configurable element
115*c33452fbSAndroid Build Coastguard Worker         const CConfigurableElement *pConfigurableElement =
116*c33452fbSAndroid Build Coastguard Worker             areaConfiguration->getConfigurableElement();
117*c33452fbSAndroid Build Coastguard Worker 
118*c33452fbSAndroid Build Coastguard Worker         // Create configurable element child element
119*c33452fbSAndroid Build Coastguard Worker         CXmlElement xmlConfigurableElementSettingsElement;
120*c33452fbSAndroid Build Coastguard Worker 
121*c33452fbSAndroid Build Coastguard Worker         xmlConfigurationSettingsElement.createChild(xmlConfigurableElementSettingsElement,
122*c33452fbSAndroid Build Coastguard Worker                                                     "ConfigurableElement");
123*c33452fbSAndroid Build Coastguard Worker 
124*c33452fbSAndroid Build Coastguard Worker         // Set Path attribute
125*c33452fbSAndroid Build Coastguard Worker         xmlConfigurableElementSettingsElement.setAttribute("Path", pConfigurableElement->getPath());
126*c33452fbSAndroid Build Coastguard Worker 
127*c33452fbSAndroid Build Coastguard Worker         // Delegate composing to area configuration
128*c33452fbSAndroid Build Coastguard Worker         exportOneConfigurableElementSettings(areaConfiguration.get(),
129*c33452fbSAndroid Build Coastguard Worker                                              xmlConfigurableElementSettingsElement, context);
130*c33452fbSAndroid Build Coastguard Worker     }
131*c33452fbSAndroid Build Coastguard Worker }
132*c33452fbSAndroid Build Coastguard Worker 
133*c33452fbSAndroid Build Coastguard Worker // Serialize one configuration for one configurable element
importOneConfigurableElementSettings(CAreaConfiguration * areaConfiguration,CXmlElement & xmlConfigurableElementSettingsElement,CXmlDomainImportContext & context)134*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::importOneConfigurableElementSettings(
135*c33452fbSAndroid Build Coastguard Worker     CAreaConfiguration *areaConfiguration, CXmlElement &xmlConfigurableElementSettingsElement,
136*c33452fbSAndroid Build Coastguard Worker     CXmlDomainImportContext &context)
137*c33452fbSAndroid Build Coastguard Worker {
138*c33452fbSAndroid Build Coastguard Worker     const CConfigurableElement *destination = areaConfiguration->getConfigurableElement();
139*c33452fbSAndroid Build Coastguard Worker 
140*c33452fbSAndroid Build Coastguard Worker     // Check structure
141*c33452fbSAndroid Build Coastguard Worker     if (xmlConfigurableElementSettingsElement.getNbChildElements() != 1) {
142*c33452fbSAndroid Build Coastguard Worker 
143*c33452fbSAndroid Build Coastguard Worker         // Structure error
144*c33452fbSAndroid Build Coastguard Worker         context.setError("Struture error encountered while parsing settings of " +
145*c33452fbSAndroid Build Coastguard Worker                          destination->getKind() + " " + destination->getName() +
146*c33452fbSAndroid Build Coastguard Worker                          " in Configuration " + getPath());
147*c33452fbSAndroid Build Coastguard Worker 
148*c33452fbSAndroid Build Coastguard Worker         return false;
149*c33452fbSAndroid Build Coastguard Worker     }
150*c33452fbSAndroid Build Coastguard Worker 
151*c33452fbSAndroid Build Coastguard Worker     // Element content
152*c33452fbSAndroid Build Coastguard Worker     CXmlElement xmlConfigurableElementSettingsElementContent;
153*c33452fbSAndroid Build Coastguard Worker     // Check name and kind
154*c33452fbSAndroid Build Coastguard Worker     if (!xmlConfigurableElementSettingsElement.getChildElement(
155*c33452fbSAndroid Build Coastguard Worker             destination->getXmlElementName(), destination->getName(),
156*c33452fbSAndroid Build Coastguard Worker             xmlConfigurableElementSettingsElementContent)) {
157*c33452fbSAndroid Build Coastguard Worker 
158*c33452fbSAndroid Build Coastguard Worker         // "Component" tag has been renamed to "ParameterBlock", but retro-compatibility shall
159*c33452fbSAndroid Build Coastguard Worker         // be ensured.
160*c33452fbSAndroid Build Coastguard Worker         //
161*c33452fbSAndroid Build Coastguard Worker         // So checking if this case occurs, i.e. element name is "ParameterBlock"
162*c33452fbSAndroid Build Coastguard Worker         // but found xml setting name is "Component".
163*c33452fbSAndroid Build Coastguard Worker         bool compatibilityCase =
164*c33452fbSAndroid Build Coastguard Worker             (destination->getXmlElementName() == "ParameterBlock") &&
165*c33452fbSAndroid Build Coastguard Worker             xmlConfigurableElementSettingsElement.getChildElement(
166*c33452fbSAndroid Build Coastguard Worker                 "Component", destination->getName(), xmlConfigurableElementSettingsElementContent);
167*c33452fbSAndroid Build Coastguard Worker 
168*c33452fbSAndroid Build Coastguard Worker         // Error if the compatibility case does not occur.
169*c33452fbSAndroid Build Coastguard Worker         if (!compatibilityCase) {
170*c33452fbSAndroid Build Coastguard Worker             context.setError("Couldn't find settings for " + destination->getXmlElementName() +
171*c33452fbSAndroid Build Coastguard Worker                              " " + destination->getName() + " for Configuration " + getPath());
172*c33452fbSAndroid Build Coastguard Worker 
173*c33452fbSAndroid Build Coastguard Worker             return false;
174*c33452fbSAndroid Build Coastguard Worker         }
175*c33452fbSAndroid Build Coastguard Worker     }
176*c33452fbSAndroid Build Coastguard Worker 
177*c33452fbSAndroid Build Coastguard Worker     // Create configuration access context
178*c33452fbSAndroid Build Coastguard Worker     string error;
179*c33452fbSAndroid Build Coastguard Worker     CConfigurationAccessContext configurationAccessContext(error, false);
180*c33452fbSAndroid Build Coastguard Worker 
181*c33452fbSAndroid Build Coastguard Worker     // Have domain configuration parse settings for configurable element
182*c33452fbSAndroid Build Coastguard Worker     bool success = areaConfiguration->serializeXmlSettings(
183*c33452fbSAndroid Build Coastguard Worker         xmlConfigurableElementSettingsElementContent, configurationAccessContext);
184*c33452fbSAndroid Build Coastguard Worker 
185*c33452fbSAndroid Build Coastguard Worker     context.appendToError(error);
186*c33452fbSAndroid Build Coastguard Worker     return success;
187*c33452fbSAndroid Build Coastguard Worker }
188*c33452fbSAndroid Build Coastguard Worker 
exportOneConfigurableElementSettings(CAreaConfiguration * areaConfiguration,CXmlElement & xmlConfigurableElementSettingsElement,CXmlDomainExportContext & context) const189*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::exportOneConfigurableElementSettings(
190*c33452fbSAndroid Build Coastguard Worker     CAreaConfiguration *areaConfiguration, CXmlElement &xmlConfigurableElementSettingsElement,
191*c33452fbSAndroid Build Coastguard Worker     CXmlDomainExportContext &context) const
192*c33452fbSAndroid Build Coastguard Worker {
193*c33452fbSAndroid Build Coastguard Worker     const CConfigurableElement *source = areaConfiguration->getConfigurableElement();
194*c33452fbSAndroid Build Coastguard Worker 
195*c33452fbSAndroid Build Coastguard Worker     // Create child XML element
196*c33452fbSAndroid Build Coastguard Worker     CXmlElement xmlConfigurableElementSettingsElementContent;
197*c33452fbSAndroid Build Coastguard Worker     xmlConfigurableElementSettingsElement.createChild(xmlConfigurableElementSettingsElementContent,
198*c33452fbSAndroid Build Coastguard Worker                                                       source->getXmlElementName());
199*c33452fbSAndroid Build Coastguard Worker 
200*c33452fbSAndroid Build Coastguard Worker     // Create configuration access context
201*c33452fbSAndroid Build Coastguard Worker     string error;
202*c33452fbSAndroid Build Coastguard Worker     CConfigurationAccessContext configurationAccessContext(error, true);
203*c33452fbSAndroid Build Coastguard Worker     configurationAccessContext.setValueSpaceRaw(context.valueSpaceIsRaw());
204*c33452fbSAndroid Build Coastguard Worker     configurationAccessContext.setOutputRawFormat(context.outputRawFormatIsHex());
205*c33452fbSAndroid Build Coastguard Worker 
206*c33452fbSAndroid Build Coastguard Worker     // Have domain configuration parse settings for configurable element
207*c33452fbSAndroid Build Coastguard Worker     bool success = areaConfiguration->serializeXmlSettings(
208*c33452fbSAndroid Build Coastguard Worker         xmlConfigurableElementSettingsElementContent, configurationAccessContext);
209*c33452fbSAndroid Build Coastguard Worker 
210*c33452fbSAndroid Build Coastguard Worker     context.appendToError(error);
211*c33452fbSAndroid Build Coastguard Worker     return success;
212*c33452fbSAndroid Build Coastguard Worker }
213*c33452fbSAndroid Build Coastguard Worker 
addConfigurableElement(const CConfigurableElement * configurableElement,const CSyncerSet * syncerSet)214*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::addConfigurableElement(const CConfigurableElement *configurableElement,
215*c33452fbSAndroid Build Coastguard Worker                                                   const CSyncerSet *syncerSet)
216*c33452fbSAndroid Build Coastguard Worker {
217*c33452fbSAndroid Build Coastguard Worker     mAreaConfigurationList.emplace_back(configurableElement->createAreaConfiguration(syncerSet));
218*c33452fbSAndroid Build Coastguard Worker }
219*c33452fbSAndroid Build Coastguard Worker 
removeConfigurableElement(const CConfigurableElement * pConfigurableElement)220*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::removeConfigurableElement(
221*c33452fbSAndroid Build Coastguard Worker     const CConfigurableElement *pConfigurableElement)
222*c33452fbSAndroid Build Coastguard Worker {
223*c33452fbSAndroid Build Coastguard Worker     auto &areaConfigurationToRemove = getAreaConfiguration(pConfigurableElement);
224*c33452fbSAndroid Build Coastguard Worker 
225*c33452fbSAndroid Build Coastguard Worker     mAreaConfigurationList.remove(areaConfigurationToRemove);
226*c33452fbSAndroid Build Coastguard Worker }
227*c33452fbSAndroid Build Coastguard Worker 
setElementSequence(const std::vector<string> & newElementSequence,string & error)228*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::setElementSequence(const std::vector<string> &newElementSequence,
229*c33452fbSAndroid Build Coastguard Worker                                               string &error)
230*c33452fbSAndroid Build Coastguard Worker {
231*c33452fbSAndroid Build Coastguard Worker     std::vector<string> elementSequenceSet;
232*c33452fbSAndroid Build Coastguard Worker     auto insertLocation = begin(mAreaConfigurationList);
233*c33452fbSAndroid Build Coastguard Worker 
234*c33452fbSAndroid Build Coastguard Worker     for (const std::string &elementPath : newElementSequence) {
235*c33452fbSAndroid Build Coastguard Worker 
236*c33452fbSAndroid Build Coastguard Worker         auto areaConfiguration = findAreaConfigurationByPath(elementPath);
237*c33452fbSAndroid Build Coastguard Worker         if (areaConfiguration == end(mAreaConfigurationList)) {
238*c33452fbSAndroid Build Coastguard Worker 
239*c33452fbSAndroid Build Coastguard Worker             error = "Element " + elementPath + " not found in domain";
240*c33452fbSAndroid Build Coastguard Worker 
241*c33452fbSAndroid Build Coastguard Worker             return false;
242*c33452fbSAndroid Build Coastguard Worker         }
243*c33452fbSAndroid Build Coastguard Worker         auto it = find(begin(elementSequenceSet), end(elementSequenceSet), elementPath);
244*c33452fbSAndroid Build Coastguard Worker         if (it != end(elementSequenceSet)) {
245*c33452fbSAndroid Build Coastguard Worker             error = "Element " + elementPath + " provided more than once";
246*c33452fbSAndroid Build Coastguard Worker             return false;
247*c33452fbSAndroid Build Coastguard Worker         }
248*c33452fbSAndroid Build Coastguard Worker         elementSequenceSet.push_back(elementPath);
249*c33452fbSAndroid Build Coastguard Worker         // Take into account the new configuration order by moving the configuration associated to
250*c33452fbSAndroid Build Coastguard Worker         // the element to the n-th position of the configuration list.
251*c33452fbSAndroid Build Coastguard Worker         // It will result in prepending to the configuration list wit the configuration of all
252*c33452fbSAndroid Build Coastguard Worker         // elements found in XML, keeping the order of the processing of the XML file.
253*c33452fbSAndroid Build Coastguard Worker         mAreaConfigurationList.splice(insertLocation, mAreaConfigurationList, areaConfiguration);
254*c33452fbSAndroid Build Coastguard Worker         // areaConfiguration is still valid, but now refer to the reorderer list
255*c33452fbSAndroid Build Coastguard Worker         insertLocation = std::next(areaConfiguration);
256*c33452fbSAndroid Build Coastguard Worker     }
257*c33452fbSAndroid Build Coastguard Worker     return true;
258*c33452fbSAndroid Build Coastguard Worker }
259*c33452fbSAndroid Build Coastguard Worker 
getElementSequence(string & strResult) const260*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::getElementSequence(string &strResult) const
261*c33452fbSAndroid Build Coastguard Worker {
262*c33452fbSAndroid Build Coastguard Worker     // List configurable element paths out of ordered area configuration list
263*c33452fbSAndroid Build Coastguard Worker     strResult = accumulate(begin(mAreaConfigurationList), end(mAreaConfigurationList), string("\n"),
264*c33452fbSAndroid Build Coastguard Worker                            [](const string &a, const AreaConfiguration &conf) {
265*c33452fbSAndroid Build Coastguard Worker                                return a + conf->getConfigurableElement()->getPath() + "\n";
266*c33452fbSAndroid Build Coastguard Worker                            });
267*c33452fbSAndroid Build Coastguard Worker }
268*c33452fbSAndroid Build Coastguard Worker 
269*c33452fbSAndroid Build Coastguard Worker // Application rule
setApplicationRule(const string & strApplicationRule,const CSelectionCriteriaDefinition * pSelectionCriteriaDefinition,string & strError)270*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::setApplicationRule(
271*c33452fbSAndroid Build Coastguard Worker     const string &strApplicationRule,
272*c33452fbSAndroid Build Coastguard Worker     const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError)
273*c33452fbSAndroid Build Coastguard Worker {
274*c33452fbSAndroid Build Coastguard Worker     // Parser
275*c33452fbSAndroid Build Coastguard Worker     CRuleParser ruleParser(strApplicationRule, pSelectionCriteriaDefinition);
276*c33452fbSAndroid Build Coastguard Worker 
277*c33452fbSAndroid Build Coastguard Worker     // Attempt to parse it
278*c33452fbSAndroid Build Coastguard Worker     if (!ruleParser.parse(nullptr, strError)) {
279*c33452fbSAndroid Build Coastguard Worker 
280*c33452fbSAndroid Build Coastguard Worker         return false;
281*c33452fbSAndroid Build Coastguard Worker     }
282*c33452fbSAndroid Build Coastguard Worker     // Replace compound rule
283*c33452fbSAndroid Build Coastguard Worker     setRule(ruleParser.grabRootRule());
284*c33452fbSAndroid Build Coastguard Worker 
285*c33452fbSAndroid Build Coastguard Worker     return true;
286*c33452fbSAndroid Build Coastguard Worker }
287*c33452fbSAndroid Build Coastguard Worker 
clearApplicationRule()288*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::clearApplicationRule()
289*c33452fbSAndroid Build Coastguard Worker {
290*c33452fbSAndroid Build Coastguard Worker     // Replace compound rule
291*c33452fbSAndroid Build Coastguard Worker     setRule(nullptr);
292*c33452fbSAndroid Build Coastguard Worker }
293*c33452fbSAndroid Build Coastguard Worker 
getApplicationRule() const294*c33452fbSAndroid Build Coastguard Worker string CDomainConfiguration::getApplicationRule() const
295*c33452fbSAndroid Build Coastguard Worker {
296*c33452fbSAndroid Build Coastguard Worker     const CCompoundRule *pRule = getRule();
297*c33452fbSAndroid Build Coastguard Worker     return pRule ? pRule->dump() : "<none>";
298*c33452fbSAndroid Build Coastguard Worker }
299*c33452fbSAndroid Build Coastguard Worker 
300*c33452fbSAndroid Build Coastguard Worker /**
301*c33452fbSAndroid Build Coastguard Worker  * Get the Configuration Blackboard.
302*c33452fbSAndroid Build Coastguard Worker  *
303*c33452fbSAndroid Build Coastguard Worker  * Fetch the Configuration Blackboard related to the ConfigurableElement given in parameter. This
304*c33452fbSAndroid Build Coastguard Worker  * Element is used to retrieve the correct AreaConfiguration where the Blackboard is stored.
305*c33452fbSAndroid Build Coastguard Worker  *
306*c33452fbSAndroid Build Coastguard Worker  * @param[in] pConfigurableElement      A pointer to a ConfigurableElement that is part of the
307*c33452fbSAndroid Build Coastguard Worker  *                                      Domain. This must have been checked previously, as an
308*c33452fbSAndroid Build Coastguard Worker  *                                      assertion is performed.
309*c33452fbSAndroid Build Coastguard Worker  *
310*c33452fbSAndroid Build Coastguard Worker  * return Pointer to the Blackboard of the Configuration.
311*c33452fbSAndroid Build Coastguard Worker  */
getBlackboard(const CConfigurableElement * pConfigurableElement) const312*c33452fbSAndroid Build Coastguard Worker CParameterBlackboard *CDomainConfiguration::getBlackboard(
313*c33452fbSAndroid Build Coastguard Worker     const CConfigurableElement *pConfigurableElement) const
314*c33452fbSAndroid Build Coastguard Worker {
315*c33452fbSAndroid Build Coastguard Worker     const auto &it = find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList),
316*c33452fbSAndroid Build Coastguard Worker                              [&](const AreaConfiguration &conf) {
317*c33452fbSAndroid Build Coastguard Worker                                  return conf != nullptr &&
318*c33452fbSAndroid Build Coastguard Worker                                         conf->getConfigurableElement() == pConfigurableElement;
319*c33452fbSAndroid Build Coastguard Worker                              });
320*c33452fbSAndroid Build Coastguard Worker     ALWAYS_ASSERT(it != end(mAreaConfigurationList), "Configurable Element "
321*c33452fbSAndroid Build Coastguard Worker                                                          << pConfigurableElement->getName()
322*c33452fbSAndroid Build Coastguard Worker                                                          << " not found in any area Configuration");
323*c33452fbSAndroid Build Coastguard Worker     return &(*it)->getBlackboard();
324*c33452fbSAndroid Build Coastguard Worker }
325*c33452fbSAndroid Build Coastguard Worker 
326*c33452fbSAndroid Build Coastguard Worker // Save data from current
save(const CParameterBlackboard * pMainBlackboard)327*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::save(const CParameterBlackboard *pMainBlackboard)
328*c33452fbSAndroid Build Coastguard Worker {
329*c33452fbSAndroid Build Coastguard Worker     // Just propagate to areas
330*c33452fbSAndroid Build Coastguard Worker     for (auto &areaConfiguration : mAreaConfigurationList) {
331*c33452fbSAndroid Build Coastguard Worker         areaConfiguration->save(pMainBlackboard);
332*c33452fbSAndroid Build Coastguard Worker     }
333*c33452fbSAndroid Build Coastguard Worker }
334*c33452fbSAndroid Build Coastguard Worker 
335*c33452fbSAndroid Build Coastguard Worker // Apply data to current
restore(CParameterBlackboard * pMainBlackboard,bool bSync,core::Results * errors) const336*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::restore(CParameterBlackboard *pMainBlackboard, bool bSync,
337*c33452fbSAndroid Build Coastguard Worker                                    core::Results *errors) const
338*c33452fbSAndroid Build Coastguard Worker {
339*c33452fbSAndroid Build Coastguard Worker     return std::accumulate(begin(mAreaConfigurationList), end(mAreaConfigurationList), true,
340*c33452fbSAndroid Build Coastguard Worker                            [&](bool accumulator, const AreaConfiguration &conf) {
341*c33452fbSAndroid Build Coastguard Worker                                return conf->restore(pMainBlackboard, bSync, errors) && accumulator;
342*c33452fbSAndroid Build Coastguard Worker                            });
343*c33452fbSAndroid Build Coastguard Worker }
344*c33452fbSAndroid Build Coastguard Worker 
345*c33452fbSAndroid Build Coastguard Worker // Ensure validity for configurable element area configuration
validate(const CConfigurableElement * pConfigurableElement,const CParameterBlackboard * pMainBlackboard)346*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::validate(const CConfigurableElement *pConfigurableElement,
347*c33452fbSAndroid Build Coastguard Worker                                     const CParameterBlackboard *pMainBlackboard)
348*c33452fbSAndroid Build Coastguard Worker {
349*c33452fbSAndroid Build Coastguard Worker     auto &areaConfigurationToValidate = getAreaConfiguration(pConfigurableElement);
350*c33452fbSAndroid Build Coastguard Worker 
351*c33452fbSAndroid Build Coastguard Worker     // Delegate
352*c33452fbSAndroid Build Coastguard Worker     areaConfigurationToValidate->validate(pMainBlackboard);
353*c33452fbSAndroid Build Coastguard Worker }
354*c33452fbSAndroid Build Coastguard Worker 
355*c33452fbSAndroid Build Coastguard Worker // Ensure validity of all area configurations
validate(const CParameterBlackboard * pMainBlackboard)356*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::validate(const CParameterBlackboard *pMainBlackboard)
357*c33452fbSAndroid Build Coastguard Worker {
358*c33452fbSAndroid Build Coastguard Worker     for (auto &areaConfiguration : mAreaConfigurationList) {
359*c33452fbSAndroid Build Coastguard Worker         areaConfiguration->validate(pMainBlackboard);
360*c33452fbSAndroid Build Coastguard Worker     }
361*c33452fbSAndroid Build Coastguard Worker }
362*c33452fbSAndroid Build Coastguard Worker 
363*c33452fbSAndroid Build Coastguard Worker // Return configuration validity for given configurable element
isValid(const CConfigurableElement * pConfigurableElement) const364*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::isValid(const CConfigurableElement *pConfigurableElement) const
365*c33452fbSAndroid Build Coastguard Worker {
366*c33452fbSAndroid Build Coastguard Worker     // Get child configurable elemnt's area configuration
367*c33452fbSAndroid Build Coastguard Worker     auto &areaConfiguration = getAreaConfiguration(pConfigurableElement);
368*c33452fbSAndroid Build Coastguard Worker 
369*c33452fbSAndroid Build Coastguard Worker     ALWAYS_ASSERT(areaConfiguration != nullptr, "Configurable Element "
370*c33452fbSAndroid Build Coastguard Worker                                                     << pConfigurableElement->getName()
371*c33452fbSAndroid Build Coastguard Worker                                                     << " not found in any area Configuration");
372*c33452fbSAndroid Build Coastguard Worker 
373*c33452fbSAndroid Build Coastguard Worker     return areaConfiguration->isValid();
374*c33452fbSAndroid Build Coastguard Worker }
375*c33452fbSAndroid Build Coastguard Worker 
376*c33452fbSAndroid Build Coastguard Worker // Ensure validity of configurable element's area configuration by copying in from a valid one
validateAgainst(const CDomainConfiguration * pValidDomainConfiguration,const CConfigurableElement * pConfigurableElement)377*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::validateAgainst(const CDomainConfiguration *pValidDomainConfiguration,
378*c33452fbSAndroid Build Coastguard Worker                                            const CConfigurableElement *pConfigurableElement)
379*c33452fbSAndroid Build Coastguard Worker {
380*c33452fbSAndroid Build Coastguard Worker     // Retrieve related area configurations
381*c33452fbSAndroid Build Coastguard Worker     auto &areaConfigurationToValidate = getAreaConfiguration(pConfigurableElement);
382*c33452fbSAndroid Build Coastguard Worker     const auto &areaConfigurationToValidateAgainst =
383*c33452fbSAndroid Build Coastguard Worker         pValidDomainConfiguration->getAreaConfiguration(pConfigurableElement);
384*c33452fbSAndroid Build Coastguard Worker 
385*c33452fbSAndroid Build Coastguard Worker     // Delegate to area
386*c33452fbSAndroid Build Coastguard Worker     areaConfigurationToValidate->validateAgainst(areaConfigurationToValidateAgainst.get());
387*c33452fbSAndroid Build Coastguard Worker }
388*c33452fbSAndroid Build Coastguard Worker 
validateAgainst(const CDomainConfiguration * validDomainConfiguration)389*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::validateAgainst(const CDomainConfiguration *validDomainConfiguration)
390*c33452fbSAndroid Build Coastguard Worker {
391*c33452fbSAndroid Build Coastguard Worker     ALWAYS_ASSERT(mAreaConfigurationList.size() ==
392*c33452fbSAndroid Build Coastguard Worker                       validDomainConfiguration->mAreaConfigurationList.size(),
393*c33452fbSAndroid Build Coastguard Worker                   "Cannot validate domain configuration "
394*c33452fbSAndroid Build Coastguard Worker                       << getPath() << " since area configuration list does not have the same size"
395*c33452fbSAndroid Build Coastguard Worker                                       "than the configuration list to check against");
396*c33452fbSAndroid Build Coastguard Worker     for (const auto &configurationToValidateAgainst :
397*c33452fbSAndroid Build Coastguard Worker          validDomainConfiguration->mAreaConfigurationList) {
398*c33452fbSAndroid Build Coastguard Worker         // Get the area configuration associated to the configurable element of the
399*c33452fbSAndroid Build Coastguard Worker         // valid area configuration, it will assert if none found.
400*c33452fbSAndroid Build Coastguard Worker         auto configurableElement = configurationToValidateAgainst->getConfigurableElement();
401*c33452fbSAndroid Build Coastguard Worker         auto &configurationToValidate = getAreaConfiguration(configurableElement);
402*c33452fbSAndroid Build Coastguard Worker         // Delegate to area
403*c33452fbSAndroid Build Coastguard Worker         configurationToValidate->validateAgainst(configurationToValidateAgainst.get());
404*c33452fbSAndroid Build Coastguard Worker     }
405*c33452fbSAndroid Build Coastguard Worker }
406*c33452fbSAndroid Build Coastguard Worker 
407*c33452fbSAndroid Build Coastguard Worker // Dynamic data application
isApplicable() const408*c33452fbSAndroid Build Coastguard Worker bool CDomainConfiguration::isApplicable() const
409*c33452fbSAndroid Build Coastguard Worker {
410*c33452fbSAndroid Build Coastguard Worker     const CCompoundRule *pRule = getRule();
411*c33452fbSAndroid Build Coastguard Worker 
412*c33452fbSAndroid Build Coastguard Worker     return pRule && pRule->matches();
413*c33452fbSAndroid Build Coastguard Worker }
414*c33452fbSAndroid Build Coastguard Worker 
415*c33452fbSAndroid Build Coastguard Worker // Merge existing configurations to given configurable element ones
merge(CConfigurableElement * pToConfigurableElement,CConfigurableElement * pFromConfigurableElement)416*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::merge(CConfigurableElement *pToConfigurableElement,
417*c33452fbSAndroid Build Coastguard Worker                                  CConfigurableElement *pFromConfigurableElement)
418*c33452fbSAndroid Build Coastguard Worker {
419*c33452fbSAndroid Build Coastguard Worker     // Retrieve related area configurations
420*c33452fbSAndroid Build Coastguard Worker     auto &areaConfigurationToMergeTo = getAreaConfiguration(pToConfigurableElement);
421*c33452fbSAndroid Build Coastguard Worker     const auto &areaConfigurationToMergeFrom = getAreaConfiguration(pFromConfigurableElement);
422*c33452fbSAndroid Build Coastguard Worker 
423*c33452fbSAndroid Build Coastguard Worker     // Do the merge
424*c33452fbSAndroid Build Coastguard Worker     areaConfigurationToMergeFrom->copyToOuter(areaConfigurationToMergeTo.get());
425*c33452fbSAndroid Build Coastguard Worker }
426*c33452fbSAndroid Build Coastguard Worker 
427*c33452fbSAndroid Build Coastguard Worker // Domain splitting
split(CConfigurableElement * pFromConfigurableElement)428*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::split(CConfigurableElement *pFromConfigurableElement)
429*c33452fbSAndroid Build Coastguard Worker {
430*c33452fbSAndroid Build Coastguard Worker     // Retrieve related area configuration
431*c33452fbSAndroid Build Coastguard Worker     const auto &areaConfigurationToSplitFrom = getAreaConfiguration(pFromConfigurableElement);
432*c33452fbSAndroid Build Coastguard Worker 
433*c33452fbSAndroid Build Coastguard Worker     // Go through children areas to copy configuration data to them
434*c33452fbSAndroid Build Coastguard Worker     size_t uiNbConfigurableElementChildren = pFromConfigurableElement->getNbChildren();
435*c33452fbSAndroid Build Coastguard Worker     size_t uiChild;
436*c33452fbSAndroid Build Coastguard Worker 
437*c33452fbSAndroid Build Coastguard Worker     for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
438*c33452fbSAndroid Build Coastguard Worker 
439*c33452fbSAndroid Build Coastguard Worker         CConfigurableElement *pToChildConfigurableElement =
440*c33452fbSAndroid Build Coastguard Worker             static_cast<CConfigurableElement *>(pFromConfigurableElement->getChild(uiChild));
441*c33452fbSAndroid Build Coastguard Worker 
442*c33452fbSAndroid Build Coastguard Worker         // Get child configurable elemnt's area configuration
443*c33452fbSAndroid Build Coastguard Worker         auto &childAreaConfiguration = getAreaConfiguration(pToChildConfigurableElement);
444*c33452fbSAndroid Build Coastguard Worker 
445*c33452fbSAndroid Build Coastguard Worker         // Do the copy
446*c33452fbSAndroid Build Coastguard Worker         childAreaConfiguration->copyFromOuter(areaConfigurationToSplitFrom.get());
447*c33452fbSAndroid Build Coastguard Worker     }
448*c33452fbSAndroid Build Coastguard Worker }
449*c33452fbSAndroid Build Coastguard Worker 
getAreaConfiguration(const CConfigurableElement * pConfigurableElement) const450*c33452fbSAndroid Build Coastguard Worker const CDomainConfiguration::AreaConfiguration &CDomainConfiguration::getAreaConfiguration(
451*c33452fbSAndroid Build Coastguard Worker     const CConfigurableElement *pConfigurableElement) const
452*c33452fbSAndroid Build Coastguard Worker {
453*c33452fbSAndroid Build Coastguard Worker     const auto &it = find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList),
454*c33452fbSAndroid Build Coastguard Worker                              [&](const AreaConfiguration &conf) {
455*c33452fbSAndroid Build Coastguard Worker                                  return conf->getConfigurableElement() == pConfigurableElement;
456*c33452fbSAndroid Build Coastguard Worker                              });
457*c33452fbSAndroid Build Coastguard Worker     ALWAYS_ASSERT(it != end(mAreaConfigurationList),
458*c33452fbSAndroid Build Coastguard Worker                   "Configurable Element " << pConfigurableElement->getName()
459*c33452fbSAndroid Build Coastguard Worker                                           << " not found in Domain Configuration list");
460*c33452fbSAndroid Build Coastguard Worker     return *it;
461*c33452fbSAndroid Build Coastguard Worker }
462*c33452fbSAndroid Build Coastguard Worker 
463*c33452fbSAndroid Build Coastguard Worker CDomainConfiguration::AreaConfigurations::iterator CDomainConfiguration::
findAreaConfigurationByPath(const std::string & configurableElementPath)464*c33452fbSAndroid Build Coastguard Worker     findAreaConfigurationByPath(const std::string &configurableElementPath)
465*c33452fbSAndroid Build Coastguard Worker {
466*c33452fbSAndroid Build Coastguard Worker     auto areaConfiguration =
467*c33452fbSAndroid Build Coastguard Worker         find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList),
468*c33452fbSAndroid Build Coastguard Worker                 [&](const AreaConfiguration &conf) {
469*c33452fbSAndroid Build Coastguard Worker                     return conf->getConfigurableElement()->getPath() == configurableElementPath;
470*c33452fbSAndroid Build Coastguard Worker                 });
471*c33452fbSAndroid Build Coastguard Worker     return areaConfiguration;
472*c33452fbSAndroid Build Coastguard Worker }
473*c33452fbSAndroid Build Coastguard Worker 
474*c33452fbSAndroid Build Coastguard Worker // Rule
getRule() const475*c33452fbSAndroid Build Coastguard Worker const CCompoundRule *CDomainConfiguration::getRule() const
476*c33452fbSAndroid Build Coastguard Worker {
477*c33452fbSAndroid Build Coastguard Worker     if (getNbChildren()) {
478*c33452fbSAndroid Build Coastguard Worker         // Rule created
479*c33452fbSAndroid Build Coastguard Worker         return static_cast<const CCompoundRule *>(getChild(ECompoundRule));
480*c33452fbSAndroid Build Coastguard Worker     }
481*c33452fbSAndroid Build Coastguard Worker     return nullptr;
482*c33452fbSAndroid Build Coastguard Worker }
483*c33452fbSAndroid Build Coastguard Worker 
getRule()484*c33452fbSAndroid Build Coastguard Worker CCompoundRule *CDomainConfiguration::getRule()
485*c33452fbSAndroid Build Coastguard Worker {
486*c33452fbSAndroid Build Coastguard Worker     if (getNbChildren()) {
487*c33452fbSAndroid Build Coastguard Worker         // Rule created
488*c33452fbSAndroid Build Coastguard Worker         return static_cast<CCompoundRule *>(getChild(ECompoundRule));
489*c33452fbSAndroid Build Coastguard Worker     }
490*c33452fbSAndroid Build Coastguard Worker     return nullptr;
491*c33452fbSAndroid Build Coastguard Worker }
492*c33452fbSAndroid Build Coastguard Worker 
setRule(CCompoundRule * pRule)493*c33452fbSAndroid Build Coastguard Worker void CDomainConfiguration::setRule(CCompoundRule *pRule)
494*c33452fbSAndroid Build Coastguard Worker {
495*c33452fbSAndroid Build Coastguard Worker     CCompoundRule *pOldRule = getRule();
496*c33452fbSAndroid Build Coastguard Worker 
497*c33452fbSAndroid Build Coastguard Worker     if (pOldRule) {
498*c33452fbSAndroid Build Coastguard Worker         // Remove previous rule
499*c33452fbSAndroid Build Coastguard Worker         removeChild(pOldRule);
500*c33452fbSAndroid Build Coastguard Worker 
501*c33452fbSAndroid Build Coastguard Worker         delete pOldRule;
502*c33452fbSAndroid Build Coastguard Worker     }
503*c33452fbSAndroid Build Coastguard Worker 
504*c33452fbSAndroid Build Coastguard Worker     // Set new one
505*c33452fbSAndroid Build Coastguard Worker     if (pRule) {
506*c33452fbSAndroid Build Coastguard Worker         // Chain
507*c33452fbSAndroid Build Coastguard Worker         addChild(pRule);
508*c33452fbSAndroid Build Coastguard Worker     }
509*c33452fbSAndroid Build Coastguard Worker }
510