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