ConfigurableDomains.cpp revision 221a25e58e92ebc450c7eaba5f3ba8153a2308ae
1/*
2 * Copyright (c) 2011-2015, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <cassert>
31#include "ConfigurableDomains.h"
32#include "ConfigurableDomain.h"
33#include "ConfigurableElement.h"
34
35#define base CElement
36
37using std::string;
38
39string CConfigurableDomains::getKind() const
40{
41    return "ConfigurableDomains";
42}
43
44bool CConfigurableDomains::childrenAreDynamic() const
45{
46    return true;
47}
48
49// Ensure validity on whole domains from main blackboard
50void CConfigurableDomains::validate(const CParameterBlackboard *pMainBlackboard)
51{
52    // Delegate to domains
53    size_t uiNbConfigurableDomains = getNbChildren();
54
55    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
56
57        CConfigurableDomain *pChildConfigurableDomain =
58            static_cast<CConfigurableDomain *>(getChild(child));
59
60        pChildConfigurableDomain->validate(pMainBlackboard);
61    }
62}
63
64// Configuration application if required
65void CConfigurableDomains::apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet &syncerSet,
66                                 bool bForce, core::Results &infos) const
67{
68    /// Delegate to domains
69
70    // Start with domains that can be synchronized all at once (with passed syncer set)
71    size_t uiNbConfigurableDomains = getNbChildren();
72
73    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
74
75        const CConfigurableDomain *pChildConfigurableDomain =
76            static_cast<const CConfigurableDomain *>(getChild(child));
77
78        std::string info;
79        // Apply and collect syncers when relevant
80        pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce, info);
81
82        if (!info.empty()) {
83            infos.push_back(info);
84        }
85    }
86    // Synchronize those collected syncers
87    syncerSet.sync(*pParameterBlackboard, false, NULL);
88
89    // Then deal with domains that need to synchronize along apply
90    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
91
92        const CConfigurableDomain *pChildConfigurableDomain =
93            static_cast<const CConfigurableDomain *>(getChild(child));
94
95        std::string info;
96        // Apply and synchronize when relevant
97        pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce, info);
98        if (!info.empty()) {
99            infos.push_back(info);
100        }
101    }
102}
103
104// From IXmlSource
105void CConfigurableDomains::toXml(CXmlElement &xmlElement,
106                                 CXmlSerializingContext &serializingContext) const
107{
108    // Set attribute
109    xmlElement.setAttribute("SystemClassName", getName());
110
111    base::childrenToXml(xmlElement, serializingContext);
112}
113
114// Configuration/Domains handling
115/// Domains
116bool CConfigurableDomains::createDomain(const string &strName, string &strError)
117{
118    // Already exists?
119    if (findChild(strName)) {
120
121        strError = "Already existing configurable domain";
122
123        return false;
124    }
125
126    // Creation/Hierarchy
127    addChild(new CConfigurableDomain(strName));
128
129    return true;
130}
131
132bool CConfigurableDomains::addDomain(CConfigurableDomain &domain, bool bOverwrite, string &strError)
133{
134    string strErrorDrop;
135
136    string strDomainName(domain.getName());
137    CConfigurableDomain *pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop);
138
139    if (pExistingDomain) {
140        if (!bOverwrite) {
141            strError = "Can't add domain \"" + strDomainName +
142                       "\" because it already exists and overwrite was not requested.";
143            return false;
144        }
145
146        deleteDomain(*pExistingDomain);
147    }
148
149    addChild(&domain);
150
151    return true;
152}
153
154void CConfigurableDomains::deleteDomain(CConfigurableDomain &configurableDomain)
155{
156    removeChild(&configurableDomain);
157
158    delete &configurableDomain;
159}
160
161bool CConfigurableDomains::deleteDomain(const string &strName, string &strError)
162{
163    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError);
164
165    if (pConfigurableDomain) {
166        deleteDomain(*pConfigurableDomain);
167        return true;
168    }
169
170    return false;
171}
172
173void CConfigurableDomains::deleteAllDomains()
174{
175    // remove Children
176    clean();
177}
178
179bool CConfigurableDomains::renameDomain(const string &strName, const string &strNewName,
180                                        string &strError)
181{
182    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError);
183
184    if (!pConfigurableDomain) {
185
186        return false;
187    }
188
189    // Rename
190    return pConfigurableDomain->rename(strNewName, strError);
191}
192
193bool CConfigurableDomains::setSequenceAwareness(const string &strDomain, bool bSequenceAware,
194                                                string &strError)
195{
196    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
197
198    if (!pConfigurableDomain) {
199
200        return false;
201    }
202
203    pConfigurableDomain->setSequenceAwareness(bSequenceAware);
204
205    return true;
206}
207
208bool CConfigurableDomains::getSequenceAwareness(const string &strDomain, bool &bSequenceAware,
209                                                string &strError) const
210{
211    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
212
213    if (!pConfigurableDomain) {
214
215        return false;
216    }
217
218    bSequenceAware = pConfigurableDomain->getSequenceAwareness();
219
220    return true;
221}
222
223/// Configurations
224bool CConfigurableDomains::listConfigurations(const string &strDomain, string &strResult) const
225{
226    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
227
228    if (!pConfigurableDomain) {
229
230        return false;
231    }
232    // delegate
233    pConfigurableDomain->listChildren(strResult);
234
235    return true;
236}
237
238bool CConfigurableDomains::createConfiguration(const string &strDomain,
239                                               const string &strConfiguration,
240                                               const CParameterBlackboard *pMainBlackboard,
241                                               string &strError)
242{
243    // Find domain
244    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
245
246    if (!pConfigurableDomain) {
247
248        return false;
249    }
250    // Delegate
251    return pConfigurableDomain->createConfiguration(strConfiguration, pMainBlackboard, strError);
252}
253
254bool CConfigurableDomains::deleteConfiguration(const string &strDomain,
255                                               const string &strConfiguration, string &strError)
256{
257    // Find domain
258    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
259
260    if (!pConfigurableDomain) {
261
262        return false;
263    }
264    // Delegate
265    return pConfigurableDomain->deleteConfiguration(strConfiguration, strError);
266}
267
268bool CConfigurableDomains::renameConfiguration(const string &strDomain,
269                                               const string &strConfigurationName,
270                                               const string &strNewConfigurationName,
271                                               string &strError)
272{
273    // Find domain
274    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
275
276    if (!pConfigurableDomain) {
277
278        return false;
279    }
280    // Delegate
281    return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName,
282                                                    strError);
283}
284
285bool CConfigurableDomains::listDomainElements(const string &strDomain, string &strResult) const
286{
287    // Find domain
288    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
289
290    if (!pConfigurableDomain) {
291
292        return false;
293    }
294    // Delegate
295    pConfigurableDomain->listAssociatedToElements(strResult);
296
297    return true;
298}
299
300bool CConfigurableDomains::split(const string &domainName, CConfigurableElement *element,
301                                 core::Results &infos)
302{
303    // Find domain
304    std::string error;
305    CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
306
307    if (domain == NULL) {
308
309        infos.push_back(error);
310        return false;
311    }
312    // Delegate
313    domain->split(element, infos);
314
315    return true;
316}
317
318void CConfigurableDomains::listAssociatedElements(string &strResult) const
319{
320    std::set<const CConfigurableElement *> configurableElementSet;
321
322    // Get all owned configurable elements
323    gatherAllOwnedConfigurableElements(configurableElementSet);
324
325    // Fill result
326    std::set<const CConfigurableElement *>::const_iterator it;
327
328    for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
329
330        const CConfigurableElement *pConfigurableElement = *it;
331
332        string strAssociatedDomainList;
333
334        pConfigurableElement->listAssociatedDomains(strAssociatedDomainList, false);
335
336        strResult += pConfigurableElement->getPath() + " [" + strAssociatedDomainList + "]\n";
337    }
338}
339
340void CConfigurableDomains::listConflictingElements(string &strResult) const
341{
342    std::set<const CConfigurableElement *> configurableElementSet;
343
344    // Get all owned configurable elements
345    gatherAllOwnedConfigurableElements(configurableElementSet);
346
347    // Fill result
348    std::set<const CConfigurableElement *>::const_iterator it;
349
350    for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) {
351
352        const CConfigurableElement *pConfigurableElement = *it;
353
354        if (pConfigurableElement->getBelongingDomainCount() > 1) {
355
356            string strBelongingDomainList;
357
358            pConfigurableElement->listBelongingDomains(strBelongingDomainList, false);
359
360            strResult += pConfigurableElement->getPath() + " contained in multiple domains: " +
361                         strBelongingDomainList + "\n";
362        }
363    }
364}
365
366void CConfigurableDomains::listDomains(string &strResult) const
367{
368    // List domains
369    size_t uiNbConfigurableDomains = getNbChildren();
370
371    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
372
373        const CConfigurableDomain *pChildConfigurableDomain =
374            static_cast<const CConfigurableDomain *>(getChild(child));
375
376        // Name
377        strResult += pChildConfigurableDomain->getName();
378
379        // Sequence awareness
380        if (pChildConfigurableDomain->getSequenceAwareness()) {
381
382            strResult += " [sequence aware]";
383        }
384        strResult += "\n";
385    }
386}
387
388// Gather configurable elements owned by any domain
389void CConfigurableDomains::gatherAllOwnedConfigurableElements(
390    std::set<const CConfigurableElement *> &configurableElementSet) const
391{
392    // Delegate to domains
393    size_t uiNbConfigurableDomains = getNbChildren();
394
395    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
396
397        const CConfigurableDomain *pChildConfigurableDomain =
398            static_cast<const CConfigurableDomain *>(getChild(child));
399
400        pChildConfigurableDomain->gatherConfigurableElements(configurableElementSet);
401    }
402}
403
404// Config restore
405bool CConfigurableDomains::restoreConfiguration(const string &domainName,
406                                                const string &configurationName,
407                                                CParameterBlackboard *mainBlackboard, bool autoSync,
408                                                core::Results &errors) const
409{
410    string error;
411    // Find domain
412    const CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
413
414    if (domain == NULL) {
415
416        errors.push_back(error);
417        return false;
418    }
419    // Delegate
420    return domain->restoreConfiguration(configurationName, mainBlackboard, autoSync, errors);
421}
422
423// Config save
424bool CConfigurableDomains::saveConfiguration(const string &strDomain,
425                                             const string &strConfiguration,
426                                             const CParameterBlackboard *pMainBlackboard,
427                                             string &strError)
428{
429    // Find domain
430    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
431
432    if (!pConfigurableDomain) {
433
434        return false;
435    }
436    // Delegate
437    return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError);
438}
439
440bool CConfigurableDomains::setElementSequence(const string &strDomain,
441                                              const string &strConfiguration,
442                                              const std::vector<string> &astrNewElementSequence,
443                                              string &strError)
444{
445    // Find domain
446    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
447
448    if (!pConfigurableDomain) {
449
450        return false;
451    }
452
453    // Delegate to domain
454    return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence,
455                                                   strError);
456}
457
458bool CConfigurableDomains::getElementSequence(const string &strDomain,
459                                              const string &strConfiguration,
460                                              string &strResult) const
461{
462    // Find domain
463    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
464
465    if (!pConfigurableDomain) {
466
467        return false;
468    }
469    // Delegate to domain
470    return pConfigurableDomain->getElementSequence(strConfiguration, strResult);
471}
472
473bool CConfigurableDomains::setApplicationRule(
474    const string &strDomain, const string &strConfiguration, const string &strApplicationRule,
475    const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError)
476{
477    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
478
479    if (!pConfigurableDomain) {
480
481        return false;
482    }
483
484    // Delegate to domain
485    return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule,
486                                                   pSelectionCriteriaDefinition, strError);
487}
488
489bool CConfigurableDomains::clearApplicationRule(const string &strDomain,
490                                                const string &strConfiguration, string &strError)
491{
492    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
493
494    if (!pConfigurableDomain) {
495
496        return false;
497    }
498
499    // Delegate to domain
500    return pConfigurableDomain->clearApplicationRule(strConfiguration, strError);
501}
502
503bool CConfigurableDomains::getApplicationRule(const string &strDomain,
504                                              const string &strConfiguration,
505                                              string &strResult) const
506{
507    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult);
508
509    if (!pConfigurableDomain) {
510
511        return false;
512    }
513
514    // Delegate to domain
515    return pConfigurableDomain->getApplicationRule(strConfiguration, strResult);
516}
517
518// Last applied configurations
519void CConfigurableDomains::listLastAppliedConfigurations(string &strResult) const
520{
521    // Browse domains
522    size_t uiNbConfigurableDomains = getNbChildren();
523
524    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {
525
526        const CConfigurableDomain *pChildConfigurableDomain =
527            static_cast<const CConfigurableDomain *>(getChild(child));
528
529        strResult += pChildConfigurableDomain->getName() + ": " +
530                     pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" +
531                     pChildConfigurableDomain->getPendingConfigurationName() + "]\n";
532    }
533}
534
535// Configurable element - domain association
536bool CConfigurableDomains::addConfigurableElementToDomain(
537    const string &domainName, CConfigurableElement *element,
538    const CParameterBlackboard *mainBlackboard, core::Results &infos)
539{
540    // Find domain
541    std::string error;
542    CConfigurableDomain *domain = findConfigurableDomain(domainName, error);
543
544    if (domain == NULL) {
545
546        infos.push_back(error);
547        return false;
548    }
549    // Delegate
550    return domain->addConfigurableElement(element, mainBlackboard, infos);
551}
552
553bool CConfigurableDomains::removeConfigurableElementFromDomain(
554    const string &strDomain, CConfigurableElement *pConfigurableElement, string &strError)
555{
556    // Find domain
557    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
558
559    if (!pConfigurableDomain) {
560
561        return false;
562    }
563    // Delegate
564    return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError);
565}
566
567CParameterBlackboard *CConfigurableDomains::findConfigurationBlackboard(
568    const string &strDomain, const string &strConfiguration,
569    const CConfigurableElement *pConfigurableElement, size_t &baseOffset, bool &bIsLastApplied,
570    string &strError) const
571{
572    // Find domain
573    const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError);
574
575    if (!pConfigurableDomain) {
576
577        return NULL;
578    }
579
580    // Check that element belongs to the domain
581    if (!pConfigurableElement->belongsTo(pConfigurableDomain)) {
582
583        strError = "Element \"" + pConfigurableElement->getPath() +
584                   "\" does not belong to domain \"" + strDomain + "\"";
585
586        return NULL;
587    }
588
589    // Find Configuration Blackboard and Base Offset
590    return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement,
591                                                            baseOffset, bIsLastApplied, strError);
592}
593
594// Domain retrieval
595CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain,
596                                                                  string &strError)
597{
598    // Call the const equivalent
599    return const_cast<CConfigurableDomain *>(
600        static_cast<const CConfigurableDomains *>(this)->findConfigurableDomain(strDomain,
601                                                                                strError));
602}
603
604const CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain,
605                                                                        string &strError) const
606{
607    // Find domain
608    const CConfigurableDomain *pConfigurableDomain =
609        static_cast<const CConfigurableDomain *>(findChild(strDomain));
610
611    if (!pConfigurableDomain) {
612
613        strError = "Configurable domain " + strDomain + " not found";
614
615        return NULL;
616    }
617
618    return pConfigurableDomain;
619}
620