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 <string>
35#include <vector>
36#include <stdint.h>
37#include "XmlSink.h"
38#include "XmlSource.h"
39
40#include "PathNavigator.h"
41
42class CXmlElementSerializingContext;
43namespace utility
44{
45class ErrorContext;
46}
47
48class PARAMETER_EXPORT CElement : public IXmlSink, public IXmlSource
49{
50public:
51    CElement(const std::string &strName = "");
52    virtual ~CElement();
53
54    // Description
55    void setDescription(const std::string &strDescription);
56    const std::string &getDescription() const;
57
58    // Name / Path
59    const std::string &getName() const;
60    void setName(const std::string &strName);
61    bool rename(const std::string &strName, std::string &strError);
62    std::string getPath() const;
63    std::string getQualifiedPath() const;
64
65    // Creation / build
66    virtual bool init(std::string &strError);
67    virtual void clean();
68
69    // Children management
70    void addChild(CElement *pChild);
71    bool removeChild(CElement *pChild);
72    void listChildren(std::string &strChildList) const;
73    std::string listQualifiedPaths(bool bDive, size_t level = 0) const;
74    void listChildrenPaths(std::string &strChildPathList) const;
75
76    // Hierarchy query
77    size_t getNbChildren() const;
78    CElement *findChildOfKind(const std::string &strKind);
79    const CElement *findChildOfKind(const std::string &strKind) const;
80    const CElement *getParent() const;
81
82    /**
83     * Get a child element (const)
84     *
85     * Note: this method will assert if given a wrong child index (>= number of children)
86     *
87     * @param[in] index the index of the child element from 0 to number of children - 1
88     * @return the child element
89     */
90    const CElement *getChild(size_t index) const;
91
92    /**
93     * Get a child element
94     *
95     * Note: this method will assert if given a wrong child index (>= number of children)
96     *
97     * @param[in] index the index of the child element from 0 to number of children - 1
98     * @return the child element
99     */
100    CElement *getChild(size_t index);
101
102    const CElement *findChild(const std::string &strName) const;
103    CElement *findChild(const std::string &strName);
104    const CElement *findDescendant(CPathNavigator &pathNavigator) const;
105    CElement *findDescendant(CPathNavigator &pathNavigator);
106    bool isDescendantOf(const CElement *pCandidateAscendant) const;
107
108    // From IXmlSink
109    virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext);
110
111    // From IXmlSource
112    virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const;
113
114    /**
115     * Serialize the children to XML
116     *
117     * This method is virtual, to be derived in case a special treatment is
118     * needed before doing so.
119     *
120     * @param[in,out] xmlElement the XML Element below which the children must
121     *                be serialized (which may or may not be the CElement
122     *                object upon which this method is called)
123     * @param[in,out] serializingContext information about the serialization
124     */
125    virtual void childrenToXml(CXmlElement &xmlElement,
126                               CXmlSerializingContext &serializingContext) const;
127
128    // Content structure dump
129    std::string dumpContent(utility::ErrorContext &errorContext, const size_t depth = 0) const;
130
131    // Element properties
132    virtual void showProperties(std::string &strResult) const;
133
134    // Class kind
135    virtual std::string getKind() const = 0;
136
137    /**
138     * Fill the Description field of the Xml Element during XML composing.
139     *
140     * @param[in,out] xmlElement to fill with the description
141     */
142    void setXmlDescriptionAttribute(CXmlElement &xmlElement) const;
143
144    /**
145     * Appends if found human readable description property.
146     *
147     * @param[out] strResult in which the description is wished to be appended.
148     */
149    void showDescriptionProperty(std::string &strResult) const;
150
151    /**
152     * Returns Xml element name used for element XML importing/exporting functionalities
153     */
154    virtual std::string getXmlElementName() const;
155
156protected:
157    // Content dumping
158    virtual std::string logValue(utility::ErrorContext &errorContext) const;
159
160    // Hierarchy
161    CElement *getParent();
162
163    /**
164     * Creates a child CElement from a child XML Element
165     *
166     * @param[in] childElement the XML element to create CElement from
167     * @param[in] elementSerializingContext the serializing context
168     *
169     * @return child a pointer on the CElement object that has been added to the tree
170     */
171    CElement *createChild(const CXmlElement &childElement,
172                          CXmlSerializingContext &elementSerializingContext);
173
174    static const std::string gDescriptionPropertyName;
175
176private:
177    // Returns Name or Kind if no Name
178    std::string getPathName() const;
179    // Returns true if children dynamic creation is to be dealt with
180    virtual bool childrenAreDynamic() const;
181    // House keeping
182    void removeChildren();
183    // Fill XmlElement during XML composing
184    void setXmlNameAttribute(CXmlElement &xmlElement) const;
185
186    // Name
187    std::string _strName;
188
189    // Description
190    std::string _strDescription;
191
192    // Child iterators
193    typedef std::vector<CElement *>::iterator ChildArrayIterator;
194    typedef std::vector<CElement *>::reverse_iterator ChildArrayReverseIterator;
195    // Children
196    std::vector<CElement *> _childArray;
197    // Parent
198    CElement *_pParent{nullptr};
199};
200