Home | History | Annotate | Download | only in parameter
      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 #pragma once
     31 
     32 #include "parameter_export.h"
     33 
     34 #include "ConfigurableElement.h"
     35 #include "Mapper.h"
     36 #include "MappingContext.h"
     37 #include <log/Logger.h>
     38 
     39 #include <list>
     40 #include <stack>
     41 #include <string>
     42 #include <vector>
     43 
     44 class CInstanceDefinition;
     45 class CComponentLibrary;
     46 class CSubsystemObject;
     47 class CSubsystemObjectCreator;
     48 class CInstanceConfigurableElement;
     49 class CMappingData;
     50 
     51 class PARAMETER_EXPORT CSubsystem : public CConfigurableElement, private IMapper
     52 {
     53     // Subsystem objects iterator
     54     typedef std::list<CSubsystemObject *>::const_iterator SubsystemObjectListIterator;
     55 
     56 public:
     57     /**
     58      * Class Constructor
     59      *
     60      * @param[in] strName subsystem name
     61      * @param[in] logger the main logger of the application
     62      */
     63     CSubsystem(const std::string &strName, core::log::Logger &logger);
     64     virtual ~CSubsystem();
     65 
     66     virtual bool structureFromXml(const CXmlElement &xmlElement,
     67                                   CXmlSerializingContext &serializingContext);
     68 
     69     // Susbsystem sanity
     70     virtual bool isAlive() const;
     71 
     72     // Resynchronization after subsystem restart needed
     73     virtual bool needResync(bool bClear);
     74 
     75     // from CElement
     76     virtual std::string getKind() const;
     77 
     78     virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const;
     79     std::string getFormattedMapping() const override;
     80 
     81     /**
     82      * Fetch mapping data of an element.
     83      *
     84      * The mapping is represented as a std::string of all the mapping data (key:value) defined in
     85      * the
     86      * context of the element.
     87      * This method gathers the mapping data found in each Element of the configurableElementPath
     88      * list to format the resulting std::string.
     89      *
     90      * @param[in] configurableElementPath List of all the ConfigurableElements found
     91      * that have a mapping. Elements are added at the end of the list, so the root Element will be
     92      * the last one.
     93      *
     94      * @return Formatted std::string of the mapping data
     95      */
     96     virtual std::string getMapping(
     97         std::list<const CConfigurableElement *> &configurableElementPath) const;
     98 
     99 protected:
    100     // Used for simulation and virtual subsystems
    101     virtual void setDefaultValues(CParameterAccessContext &parameterAccessContext) const;
    102 
    103     /// Functionality intendedn for derived Subsystems
    104     // Subsystem context mapping keys publication
    105     void addContextMappingKey(const std::string &strMappingKey);
    106     // Subsystem object creator publication (strong reference)
    107     void addSubsystemObjectFactory(CSubsystemObjectCreator *pSubsystemObjectCreator);
    108 
    109 private:
    110     CSubsystem(const CSubsystem &);
    111     CSubsystem &operator=(const CSubsystem &);
    112 
    113     // Belonging subsystem
    114     virtual const CSubsystem *getBelongingSubsystem() const;
    115 
    116     // Mapping execution
    117     bool mapSubsystemElements(std::string &strError);
    118 
    119     /**
    120      * Handle a configurable element mapping.
    121      *
    122      * Add context mappings to the context and instantiate a subsystem object if needed.
    123      *
    124      * @param[in,out] pInstanceConfigurableElement The configurable element
    125      * @param[out] bKeepDiving Keep diving for mapping keys
    126                    Is set to true if a subsystem object (tree leave) has been instantiated.
    127                    Undetermined on error
    128      * @param[out] strError String filled with an human readable error on error,
    129                    left unmodified otherwise
    130      *
    131      * @return true on success, false on failure
    132      */
    133     virtual bool mapBegin(CInstanceConfigurableElement *pInstanceConfigurableElement,
    134                           bool &bKeepDiving, std::string &strError);
    135     virtual void mapEnd();
    136 
    137     // Mapping access
    138     /**
    139      * Generic mapping error handling
    140      *
    141      * Format an human readable error std::string from a key and a message in case of mapping error
    142      *
    143      * @param[in] strKey The key on which the error refers
    144      * @param[in] strMessage The error message
    145      * @param[in] pConfigurableElement The element on which the error refers
    146      *
    147      * returns The formated error std::string
    148      */
    149     std::string getMappingError(const std::string &strKey, const std::string &strMessage,
    150                                 const CConfigurableElement *pConfigurableElement) const;
    151 
    152     /**
    153      * Format the mapping data of the ConfigurableElements that have been gathered through recursive
    154      * calls to the getMapping() method.
    155      * These elements shall be evaluated from the root level to the leaves level, so the list must
    156      * be parsed in reverse order.
    157      *
    158      * @param[in] configurableElementPath List of ConfigurableElements containing mapping data
    159      *
    160      * @return String containing the formatted mapping
    161      */
    162     std::string formatMappingDataList(
    163         const std::list<const CConfigurableElement *> &configurableElementPath) const;
    164 
    165     /**
    166      * Find the SubystemObject which contains a specific CInstanceConfigurableElement.
    167      *
    168      * @param[in] pInstanceConfigurableElement The CInstanceConfigurableElement that is related to
    169      * the wanted SubsystemObject. Each SubsystemObject of the Subystem internal list is checked in
    170      * order to find a match.
    171      *
    172      * @return A pointer to the SubsystemObject related to pInstanceConfigurableElement
    173      */
    174     const CSubsystemObject *findSubsystemObjectFromConfigurableElement(
    175         const CInstanceConfigurableElement *pInstanceConfigurableElement) const;
    176 
    177     /**
    178      * Find the mapping data defined for the CInstanceConfigurableElement given in parameter, that
    179      * corresponds to Subsystem level mapping (Subsystem level mapping keys are defined in
    180      * CSubsystemObjectCreator classes).
    181      * The CInstanceConfigurableElement might as well contain local mapping data.
    182      *
    183      * @param[in] pInstanceConfigurableElement The element which mapping data will be parsed for
    184      * a match
    185      * @param[out] strMappingKey Mapping key defined at the Subsystem level
    186      * @param[out] strMappingValue Mapping value contained in pInstanceConfigurableElement
    187      */
    188     void findSubsystemLevelMappingKeyValue(
    189         const CInstanceConfigurableElement *pInstanceConfigurableElement,
    190         std::string &strMappingKey, std::string &strMappingValue) const;
    191 
    192     /**
    193      * Formats the mapping of a SubsystemObject
    194      *
    195      * @param[in] pInstanceConfigurableElement Element corresponding to a SubsystemObject
    196      *
    197      * @return String containing the formatted mapping
    198      */
    199     std::string getFormattedSubsystemMappingData(
    200         const CInstanceConfigurableElement *pInstanceConfigurableElement) const;
    201     /**
    202      * Generic context handling
    203      *
    204      * Feed context with mapping data of the current element
    205      *
    206      * @param[in] pConfigurableElement The element containing mapping data
    207      * @param[out] context The context mapping to update with the current element mapping values
    208      * @param[out] strError The formated error std::string
    209      *
    210      * @return true on success
    211      */
    212     bool handleMappingContext(const CConfigurableElement *pConfigurableElement,
    213                               CMappingContext &context, std::string &strError) const;
    214 
    215     /**
    216      * Looks if a subsystem object needs to be instantiated for the given configurable
    217      * element, then instantiate it if needed.
    218      *
    219      * @param[in,out] pInstanceConfigurableElement The configurable element to check
    220      *            for instanciation
    221      * @param[in] context The mapping values container
    222      * @param[out] bHasCreatedSubsystemObject If a subsystem object has been instantiated.
    223                    Undetermined on error
    224      * @param[out] strError String filled with an human readable error on error,
    225                    left unmodified otherwise
    226      *
    227      * @return true on success, false on failure
    228      */
    229     bool handleSubsystemObjectCreation(CInstanceConfigurableElement *pInstanceConfigurableElement,
    230                                        CMappingContext &context, bool &bHasCreatedSubsystemObject,
    231                                        std::string &strError);
    232 
    233     // Subsystem context mapping keys
    234     std::vector<std::string> _contextMappingKeyArray;
    235 
    236     // Subsystem object creator map
    237     std::vector<CSubsystemObjectCreator *> _subsystemObjectCreatorArray;
    238 
    239     // Subsystem sync objects (house keeping)
    240     std::list<CSubsystemObject *> _subsystemObjectList;
    241 
    242     // Mapping Context stack
    243     std::stack<CMappingContext> _contextStack;
    244 
    245     // Subelements
    246     CComponentLibrary *_pComponentLibrary;
    247     CInstanceDefinition *_pInstanceDefinition;
    248 
    249     //! Contains the mapping info at Subsystem level
    250     CMappingData *_pMappingData{nullptr};
    251 
    252     /** Logger which has to be provided to subsystem objects */
    253     core::log::Logger &_logger;
    254 };
    255