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 "Element.h"
31*c33452fbSAndroid Build Coastguard Worker #include "XmlElementSerializingContext.h"
32*c33452fbSAndroid Build Coastguard Worker #include "ElementLibrary.h"
33*c33452fbSAndroid Build Coastguard Worker #include "ErrorContext.hpp"
34*c33452fbSAndroid Build Coastguard Worker #include "PfError.hpp"
35*c33452fbSAndroid Build Coastguard Worker #include <algorithm>
36*c33452fbSAndroid Build Coastguard Worker #include <assert.h>
37*c33452fbSAndroid Build Coastguard Worker #include <stdio.h>
38*c33452fbSAndroid Build Coastguard Worker #include <stdarg.h>
39*c33452fbSAndroid Build Coastguard Worker #include <stdlib.h>
40*c33452fbSAndroid Build Coastguard Worker
41*c33452fbSAndroid Build Coastguard Worker using std::string;
42*c33452fbSAndroid Build Coastguard Worker
43*c33452fbSAndroid Build Coastguard Worker const std::string CElement::gDescriptionPropertyName = "Description";
44*c33452fbSAndroid Build Coastguard Worker
CElement(const string & strName)45*c33452fbSAndroid Build Coastguard Worker CElement::CElement(const string &strName) : _strName(strName)
46*c33452fbSAndroid Build Coastguard Worker {
47*c33452fbSAndroid Build Coastguard Worker }
48*c33452fbSAndroid Build Coastguard Worker
~CElement()49*c33452fbSAndroid Build Coastguard Worker CElement::~CElement()
50*c33452fbSAndroid Build Coastguard Worker {
51*c33452fbSAndroid Build Coastguard Worker removeChildren();
52*c33452fbSAndroid Build Coastguard Worker }
53*c33452fbSAndroid Build Coastguard Worker
setDescription(const string & strDescription)54*c33452fbSAndroid Build Coastguard Worker void CElement::setDescription(const string &strDescription)
55*c33452fbSAndroid Build Coastguard Worker {
56*c33452fbSAndroid Build Coastguard Worker _strDescription = strDescription;
57*c33452fbSAndroid Build Coastguard Worker }
58*c33452fbSAndroid Build Coastguard Worker
getDescription() const59*c33452fbSAndroid Build Coastguard Worker const string &CElement::getDescription() const
60*c33452fbSAndroid Build Coastguard Worker {
61*c33452fbSAndroid Build Coastguard Worker return _strDescription;
62*c33452fbSAndroid Build Coastguard Worker }
63*c33452fbSAndroid Build Coastguard Worker
childrenAreDynamic() const64*c33452fbSAndroid Build Coastguard Worker bool CElement::childrenAreDynamic() const
65*c33452fbSAndroid Build Coastguard Worker {
66*c33452fbSAndroid Build Coastguard Worker // By default, children are searched and not created during xml parsing
67*c33452fbSAndroid Build Coastguard Worker return false;
68*c33452fbSAndroid Build Coastguard Worker }
69*c33452fbSAndroid Build Coastguard Worker
init(string & strError)70*c33452fbSAndroid Build Coastguard Worker bool CElement::init(string &strError)
71*c33452fbSAndroid Build Coastguard Worker {
72*c33452fbSAndroid Build Coastguard Worker
73*c33452fbSAndroid Build Coastguard Worker for (CElement *child : _childArray) {
74*c33452fbSAndroid Build Coastguard Worker
75*c33452fbSAndroid Build Coastguard Worker if (!child->init(strError)) {
76*c33452fbSAndroid Build Coastguard Worker
77*c33452fbSAndroid Build Coastguard Worker return false;
78*c33452fbSAndroid Build Coastguard Worker }
79*c33452fbSAndroid Build Coastguard Worker }
80*c33452fbSAndroid Build Coastguard Worker
81*c33452fbSAndroid Build Coastguard Worker return true;
82*c33452fbSAndroid Build Coastguard Worker }
83*c33452fbSAndroid Build Coastguard Worker
dumpContent(utility::ErrorContext & errorContext,const size_t depth) const84*c33452fbSAndroid Build Coastguard Worker string CElement::dumpContent(utility::ErrorContext &errorContext, const size_t depth) const
85*c33452fbSAndroid Build Coastguard Worker {
86*c33452fbSAndroid Build Coastguard Worker string output;
87*c33452fbSAndroid Build Coastguard Worker string strIndent;
88*c33452fbSAndroid Build Coastguard Worker
89*c33452fbSAndroid Build Coastguard Worker // Level
90*c33452fbSAndroid Build Coastguard Worker size_t indents = depth;
91*c33452fbSAndroid Build Coastguard Worker
92*c33452fbSAndroid Build Coastguard Worker while (indents--) {
93*c33452fbSAndroid Build Coastguard Worker
94*c33452fbSAndroid Build Coastguard Worker strIndent += " ";
95*c33452fbSAndroid Build Coastguard Worker }
96*c33452fbSAndroid Build Coastguard Worker // Type
97*c33452fbSAndroid Build Coastguard Worker output += strIndent + "- " + getKind();
98*c33452fbSAndroid Build Coastguard Worker
99*c33452fbSAndroid Build Coastguard Worker // Name
100*c33452fbSAndroid Build Coastguard Worker if (!_strName.empty()) {
101*c33452fbSAndroid Build Coastguard Worker
102*c33452fbSAndroid Build Coastguard Worker output += ": " + getName();
103*c33452fbSAndroid Build Coastguard Worker }
104*c33452fbSAndroid Build Coastguard Worker
105*c33452fbSAndroid Build Coastguard Worker // Value
106*c33452fbSAndroid Build Coastguard Worker string strValue = logValue(errorContext);
107*c33452fbSAndroid Build Coastguard Worker
108*c33452fbSAndroid Build Coastguard Worker if (!strValue.empty()) {
109*c33452fbSAndroid Build Coastguard Worker
110*c33452fbSAndroid Build Coastguard Worker output += " = " + strValue;
111*c33452fbSAndroid Build Coastguard Worker }
112*c33452fbSAndroid Build Coastguard Worker
113*c33452fbSAndroid Build Coastguard Worker output += "\n";
114*c33452fbSAndroid Build Coastguard Worker
115*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
116*c33452fbSAndroid Build Coastguard Worker
117*c33452fbSAndroid Build Coastguard Worker output += pChild->dumpContent(errorContext, depth + 1);
118*c33452fbSAndroid Build Coastguard Worker }
119*c33452fbSAndroid Build Coastguard Worker
120*c33452fbSAndroid Build Coastguard Worker return output;
121*c33452fbSAndroid Build Coastguard Worker }
122*c33452fbSAndroid Build Coastguard Worker
123*c33452fbSAndroid Build Coastguard Worker // Element properties
showProperties(string & strResult) const124*c33452fbSAndroid Build Coastguard Worker void CElement::showProperties(string &strResult) const
125*c33452fbSAndroid Build Coastguard Worker {
126*c33452fbSAndroid Build Coastguard Worker strResult += "Kind: " + getKind() + "\n";
127*c33452fbSAndroid Build Coastguard Worker showDescriptionProperty(strResult);
128*c33452fbSAndroid Build Coastguard Worker }
129*c33452fbSAndroid Build Coastguard Worker
showDescriptionProperty(std::string & strResult) const130*c33452fbSAndroid Build Coastguard Worker void CElement::showDescriptionProperty(std::string &strResult) const
131*c33452fbSAndroid Build Coastguard Worker {
132*c33452fbSAndroid Build Coastguard Worker if (!getDescription().empty()) {
133*c33452fbSAndroid Build Coastguard Worker strResult += gDescriptionPropertyName + ": " + getDescription() + "\n";
134*c33452fbSAndroid Build Coastguard Worker }
135*c33452fbSAndroid Build Coastguard Worker }
136*c33452fbSAndroid Build Coastguard Worker
137*c33452fbSAndroid Build Coastguard Worker // Content dumping
logValue(utility::ErrorContext &) const138*c33452fbSAndroid Build Coastguard Worker string CElement::logValue(utility::ErrorContext & /*ctx*/) const
139*c33452fbSAndroid Build Coastguard Worker {
140*c33452fbSAndroid Build Coastguard Worker return "";
141*c33452fbSAndroid Build Coastguard Worker }
142*c33452fbSAndroid Build Coastguard Worker
143*c33452fbSAndroid Build Coastguard Worker // From IXmlSink
fromXml(const CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)144*c33452fbSAndroid Build Coastguard Worker bool CElement::fromXml(const CXmlElement &xmlElement,
145*c33452fbSAndroid Build Coastguard Worker CXmlSerializingContext &serializingContext) try {
146*c33452fbSAndroid Build Coastguard Worker xmlElement.getAttribute(gDescriptionPropertyName, _strDescription);
147*c33452fbSAndroid Build Coastguard Worker
148*c33452fbSAndroid Build Coastguard Worker // Propagate through children
149*c33452fbSAndroid Build Coastguard Worker CXmlElement::CChildIterator childIterator(xmlElement);
150*c33452fbSAndroid Build Coastguard Worker
151*c33452fbSAndroid Build Coastguard Worker CXmlElement childElement;
152*c33452fbSAndroid Build Coastguard Worker
153*c33452fbSAndroid Build Coastguard Worker while (childIterator.next(childElement)) {
154*c33452fbSAndroid Build Coastguard Worker
155*c33452fbSAndroid Build Coastguard Worker CElement *pChild;
156*c33452fbSAndroid Build Coastguard Worker
157*c33452fbSAndroid Build Coastguard Worker if (!childrenAreDynamic()) {
158*c33452fbSAndroid Build Coastguard Worker
159*c33452fbSAndroid Build Coastguard Worker pChild = findChildOfKind(childElement.getType());
160*c33452fbSAndroid Build Coastguard Worker
161*c33452fbSAndroid Build Coastguard Worker if (!pChild) {
162*c33452fbSAndroid Build Coastguard Worker
163*c33452fbSAndroid Build Coastguard Worker serializingContext.setError("Unable to handle XML element: " +
164*c33452fbSAndroid Build Coastguard Worker childElement.getPath());
165*c33452fbSAndroid Build Coastguard Worker
166*c33452fbSAndroid Build Coastguard Worker return false;
167*c33452fbSAndroid Build Coastguard Worker }
168*c33452fbSAndroid Build Coastguard Worker
169*c33452fbSAndroid Build Coastguard Worker } else {
170*c33452fbSAndroid Build Coastguard Worker // Child needs creation
171*c33452fbSAndroid Build Coastguard Worker pChild = createChild(childElement, serializingContext);
172*c33452fbSAndroid Build Coastguard Worker
173*c33452fbSAndroid Build Coastguard Worker if (!pChild) {
174*c33452fbSAndroid Build Coastguard Worker
175*c33452fbSAndroid Build Coastguard Worker return false;
176*c33452fbSAndroid Build Coastguard Worker }
177*c33452fbSAndroid Build Coastguard Worker }
178*c33452fbSAndroid Build Coastguard Worker
179*c33452fbSAndroid Build Coastguard Worker // Dig
180*c33452fbSAndroid Build Coastguard Worker if (!pChild->fromXml(childElement, serializingContext)) {
181*c33452fbSAndroid Build Coastguard Worker
182*c33452fbSAndroid Build Coastguard Worker return false;
183*c33452fbSAndroid Build Coastguard Worker }
184*c33452fbSAndroid Build Coastguard Worker }
185*c33452fbSAndroid Build Coastguard Worker
186*c33452fbSAndroid Build Coastguard Worker return true;
187*c33452fbSAndroid Build Coastguard Worker } catch (const PfError &e) {
188*c33452fbSAndroid Build Coastguard Worker serializingContext.appendLineToError(e.what());
189*c33452fbSAndroid Build Coastguard Worker return false;
190*c33452fbSAndroid Build Coastguard Worker }
191*c33452fbSAndroid Build Coastguard Worker
childrenToXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const192*c33452fbSAndroid Build Coastguard Worker void CElement::childrenToXml(CXmlElement &xmlElement,
193*c33452fbSAndroid Build Coastguard Worker CXmlSerializingContext &serializingContext) const
194*c33452fbSAndroid Build Coastguard Worker {
195*c33452fbSAndroid Build Coastguard Worker // Browse children and propagate
196*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
197*c33452fbSAndroid Build Coastguard Worker
198*c33452fbSAndroid Build Coastguard Worker // Create corresponding child element
199*c33452fbSAndroid Build Coastguard Worker CXmlElement xmlChildElement;
200*c33452fbSAndroid Build Coastguard Worker
201*c33452fbSAndroid Build Coastguard Worker xmlElement.createChild(xmlChildElement, pChild->getXmlElementName());
202*c33452fbSAndroid Build Coastguard Worker
203*c33452fbSAndroid Build Coastguard Worker // Propagate
204*c33452fbSAndroid Build Coastguard Worker pChild->toXml(xmlChildElement, serializingContext);
205*c33452fbSAndroid Build Coastguard Worker }
206*c33452fbSAndroid Build Coastguard Worker }
207*c33452fbSAndroid Build Coastguard Worker
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const208*c33452fbSAndroid Build Coastguard Worker void CElement::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const
209*c33452fbSAndroid Build Coastguard Worker {
210*c33452fbSAndroid Build Coastguard Worker setXmlNameAttribute(xmlElement);
211*c33452fbSAndroid Build Coastguard Worker setXmlDescriptionAttribute(xmlElement);
212*c33452fbSAndroid Build Coastguard Worker childrenToXml(xmlElement, serializingContext);
213*c33452fbSAndroid Build Coastguard Worker }
214*c33452fbSAndroid Build Coastguard Worker
setXmlDescriptionAttribute(CXmlElement & xmlElement) const215*c33452fbSAndroid Build Coastguard Worker void CElement::setXmlDescriptionAttribute(CXmlElement &xmlElement) const
216*c33452fbSAndroid Build Coastguard Worker {
217*c33452fbSAndroid Build Coastguard Worker const string &description = getDescription();
218*c33452fbSAndroid Build Coastguard Worker if (!description.empty()) {
219*c33452fbSAndroid Build Coastguard Worker xmlElement.setAttribute(gDescriptionPropertyName, description);
220*c33452fbSAndroid Build Coastguard Worker }
221*c33452fbSAndroid Build Coastguard Worker }
222*c33452fbSAndroid Build Coastguard Worker
setXmlNameAttribute(CXmlElement & xmlElement) const223*c33452fbSAndroid Build Coastguard Worker void CElement::setXmlNameAttribute(CXmlElement &xmlElement) const
224*c33452fbSAndroid Build Coastguard Worker {
225*c33452fbSAndroid Build Coastguard Worker // By default, set Name attribute if any
226*c33452fbSAndroid Build Coastguard Worker string strName = getName();
227*c33452fbSAndroid Build Coastguard Worker
228*c33452fbSAndroid Build Coastguard Worker if (!strName.empty()) {
229*c33452fbSAndroid Build Coastguard Worker
230*c33452fbSAndroid Build Coastguard Worker xmlElement.setNameAttribute(strName);
231*c33452fbSAndroid Build Coastguard Worker }
232*c33452fbSAndroid Build Coastguard Worker }
233*c33452fbSAndroid Build Coastguard Worker
234*c33452fbSAndroid Build Coastguard Worker // Name
setName(const string & strName)235*c33452fbSAndroid Build Coastguard Worker void CElement::setName(const string &strName)
236*c33452fbSAndroid Build Coastguard Worker {
237*c33452fbSAndroid Build Coastguard Worker _strName = strName;
238*c33452fbSAndroid Build Coastguard Worker }
239*c33452fbSAndroid Build Coastguard Worker
getName() const240*c33452fbSAndroid Build Coastguard Worker const string &CElement::getName() const
241*c33452fbSAndroid Build Coastguard Worker {
242*c33452fbSAndroid Build Coastguard Worker return _strName;
243*c33452fbSAndroid Build Coastguard Worker }
244*c33452fbSAndroid Build Coastguard Worker
rename(const string & strName,string & strError)245*c33452fbSAndroid Build Coastguard Worker bool CElement::rename(const string &strName, string &strError)
246*c33452fbSAndroid Build Coastguard Worker {
247*c33452fbSAndroid Build Coastguard Worker // Check for conflict with brotherhood if relevant
248*c33452fbSAndroid Build Coastguard Worker if (_pParent && _pParent->childrenAreDynamic()) {
249*c33452fbSAndroid Build Coastguard Worker
250*c33452fbSAndroid Build Coastguard Worker for (CElement *pParentChild : _pParent->_childArray) {
251*c33452fbSAndroid Build Coastguard Worker
252*c33452fbSAndroid Build Coastguard Worker if (pParentChild != this && pParentChild->getName() == strName) {
253*c33452fbSAndroid Build Coastguard Worker
254*c33452fbSAndroid Build Coastguard Worker // Conflict
255*c33452fbSAndroid Build Coastguard Worker strError = "Name conflicts with brother element";
256*c33452fbSAndroid Build Coastguard Worker
257*c33452fbSAndroid Build Coastguard Worker return false;
258*c33452fbSAndroid Build Coastguard Worker }
259*c33452fbSAndroid Build Coastguard Worker }
260*c33452fbSAndroid Build Coastguard Worker }
261*c33452fbSAndroid Build Coastguard Worker // Change name
262*c33452fbSAndroid Build Coastguard Worker setName(strName);
263*c33452fbSAndroid Build Coastguard Worker
264*c33452fbSAndroid Build Coastguard Worker return true;
265*c33452fbSAndroid Build Coastguard Worker }
266*c33452fbSAndroid Build Coastguard Worker
getPathName() const267*c33452fbSAndroid Build Coastguard Worker string CElement::getPathName() const
268*c33452fbSAndroid Build Coastguard Worker {
269*c33452fbSAndroid Build Coastguard Worker if (!_strName.empty()) {
270*c33452fbSAndroid Build Coastguard Worker
271*c33452fbSAndroid Build Coastguard Worker return _strName;
272*c33452fbSAndroid Build Coastguard Worker } else {
273*c33452fbSAndroid Build Coastguard Worker
274*c33452fbSAndroid Build Coastguard Worker return getKind();
275*c33452fbSAndroid Build Coastguard Worker }
276*c33452fbSAndroid Build Coastguard Worker }
277*c33452fbSAndroid Build Coastguard Worker
278*c33452fbSAndroid Build Coastguard Worker // Hierarchy
addChild(CElement * pChild)279*c33452fbSAndroid Build Coastguard Worker void CElement::addChild(CElement *pChild)
280*c33452fbSAndroid Build Coastguard Worker {
281*c33452fbSAndroid Build Coastguard Worker _childArray.push_back(pChild);
282*c33452fbSAndroid Build Coastguard Worker
283*c33452fbSAndroid Build Coastguard Worker pChild->_pParent = this;
284*c33452fbSAndroid Build Coastguard Worker }
285*c33452fbSAndroid Build Coastguard Worker
getChild(size_t index)286*c33452fbSAndroid Build Coastguard Worker CElement *CElement::getChild(size_t index)
287*c33452fbSAndroid Build Coastguard Worker {
288*c33452fbSAndroid Build Coastguard Worker assert(index <= _childArray.size());
289*c33452fbSAndroid Build Coastguard Worker
290*c33452fbSAndroid Build Coastguard Worker return _childArray[index];
291*c33452fbSAndroid Build Coastguard Worker }
292*c33452fbSAndroid Build Coastguard Worker
getChild(size_t index) const293*c33452fbSAndroid Build Coastguard Worker const CElement *CElement::getChild(size_t index) const
294*c33452fbSAndroid Build Coastguard Worker {
295*c33452fbSAndroid Build Coastguard Worker assert(index <= _childArray.size());
296*c33452fbSAndroid Build Coastguard Worker
297*c33452fbSAndroid Build Coastguard Worker return _childArray[index];
298*c33452fbSAndroid Build Coastguard Worker }
299*c33452fbSAndroid Build Coastguard Worker
createChild(const CXmlElement & childElement,CXmlSerializingContext & serializingContext)300*c33452fbSAndroid Build Coastguard Worker CElement *CElement::createChild(const CXmlElement &childElement,
301*c33452fbSAndroid Build Coastguard Worker CXmlSerializingContext &serializingContext)
302*c33452fbSAndroid Build Coastguard Worker {
303*c33452fbSAndroid Build Coastguard Worker // Context
304*c33452fbSAndroid Build Coastguard Worker CXmlElementSerializingContext &elementSerializingContext =
305*c33452fbSAndroid Build Coastguard Worker static_cast<CXmlElementSerializingContext &>(serializingContext);
306*c33452fbSAndroid Build Coastguard Worker
307*c33452fbSAndroid Build Coastguard Worker // Child needs creation
308*c33452fbSAndroid Build Coastguard Worker CElement *pChild = elementSerializingContext.getElementLibrary()->createElement(childElement);
309*c33452fbSAndroid Build Coastguard Worker
310*c33452fbSAndroid Build Coastguard Worker if (!pChild) {
311*c33452fbSAndroid Build Coastguard Worker
312*c33452fbSAndroid Build Coastguard Worker elementSerializingContext.setError("Unable to create XML element " +
313*c33452fbSAndroid Build Coastguard Worker childElement.getPath());
314*c33452fbSAndroid Build Coastguard Worker
315*c33452fbSAndroid Build Coastguard Worker return nullptr;
316*c33452fbSAndroid Build Coastguard Worker }
317*c33452fbSAndroid Build Coastguard Worker // Store created child!
318*c33452fbSAndroid Build Coastguard Worker addChild(pChild);
319*c33452fbSAndroid Build Coastguard Worker
320*c33452fbSAndroid Build Coastguard Worker return pChild;
321*c33452fbSAndroid Build Coastguard Worker }
322*c33452fbSAndroid Build Coastguard Worker
removeChild(CElement * pChild)323*c33452fbSAndroid Build Coastguard Worker bool CElement::removeChild(CElement *pChild)
324*c33452fbSAndroid Build Coastguard Worker {
325*c33452fbSAndroid Build Coastguard Worker auto childIt = find(begin(_childArray), end(_childArray), pChild);
326*c33452fbSAndroid Build Coastguard Worker if (childIt != end(_childArray)) {
327*c33452fbSAndroid Build Coastguard Worker
328*c33452fbSAndroid Build Coastguard Worker _childArray.erase(childIt);
329*c33452fbSAndroid Build Coastguard Worker return true;
330*c33452fbSAndroid Build Coastguard Worker }
331*c33452fbSAndroid Build Coastguard Worker return false;
332*c33452fbSAndroid Build Coastguard Worker }
333*c33452fbSAndroid Build Coastguard Worker
listChildren(string & strChildList) const334*c33452fbSAndroid Build Coastguard Worker void CElement::listChildren(string &strChildList) const
335*c33452fbSAndroid Build Coastguard Worker {
336*c33452fbSAndroid Build Coastguard Worker // Get list of children names
337*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
338*c33452fbSAndroid Build Coastguard Worker
339*c33452fbSAndroid Build Coastguard Worker strChildList += pChild->getName() + "\n";
340*c33452fbSAndroid Build Coastguard Worker }
341*c33452fbSAndroid Build Coastguard Worker }
342*c33452fbSAndroid Build Coastguard Worker
listQualifiedPaths(bool bDive,size_t level) const343*c33452fbSAndroid Build Coastguard Worker string CElement::listQualifiedPaths(bool bDive, size_t level) const
344*c33452fbSAndroid Build Coastguard Worker {
345*c33452fbSAndroid Build Coastguard Worker string strResult;
346*c33452fbSAndroid Build Coastguard Worker
347*c33452fbSAndroid Build Coastguard Worker // Dive Will cause only leaf nodes to be printed
348*c33452fbSAndroid Build Coastguard Worker if (!bDive || !getNbChildren()) {
349*c33452fbSAndroid Build Coastguard Worker
350*c33452fbSAndroid Build Coastguard Worker strResult = getQualifiedPath() + "\n";
351*c33452fbSAndroid Build Coastguard Worker }
352*c33452fbSAndroid Build Coastguard Worker
353*c33452fbSAndroid Build Coastguard Worker if (bDive || !level) {
354*c33452fbSAndroid Build Coastguard Worker // Get list of children paths
355*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
356*c33452fbSAndroid Build Coastguard Worker
357*c33452fbSAndroid Build Coastguard Worker strResult += pChild->listQualifiedPaths(bDive, level + 1);
358*c33452fbSAndroid Build Coastguard Worker }
359*c33452fbSAndroid Build Coastguard Worker }
360*c33452fbSAndroid Build Coastguard Worker return strResult;
361*c33452fbSAndroid Build Coastguard Worker }
362*c33452fbSAndroid Build Coastguard Worker
listChildrenPaths(string & strChildList) const363*c33452fbSAndroid Build Coastguard Worker void CElement::listChildrenPaths(string &strChildList) const
364*c33452fbSAndroid Build Coastguard Worker {
365*c33452fbSAndroid Build Coastguard Worker // Get list of children paths
366*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
367*c33452fbSAndroid Build Coastguard Worker
368*c33452fbSAndroid Build Coastguard Worker strChildList += pChild->getPath() + "\n";
369*c33452fbSAndroid Build Coastguard Worker }
370*c33452fbSAndroid Build Coastguard Worker }
371*c33452fbSAndroid Build Coastguard Worker
getNbChildren() const372*c33452fbSAndroid Build Coastguard Worker size_t CElement::getNbChildren() const
373*c33452fbSAndroid Build Coastguard Worker {
374*c33452fbSAndroid Build Coastguard Worker return _childArray.size();
375*c33452fbSAndroid Build Coastguard Worker }
376*c33452fbSAndroid Build Coastguard Worker
getParent() const377*c33452fbSAndroid Build Coastguard Worker const CElement *CElement::getParent() const
378*c33452fbSAndroid Build Coastguard Worker {
379*c33452fbSAndroid Build Coastguard Worker return _pParent;
380*c33452fbSAndroid Build Coastguard Worker }
381*c33452fbSAndroid Build Coastguard Worker
getParent()382*c33452fbSAndroid Build Coastguard Worker CElement *CElement::getParent()
383*c33452fbSAndroid Build Coastguard Worker {
384*c33452fbSAndroid Build Coastguard Worker return _pParent;
385*c33452fbSAndroid Build Coastguard Worker }
386*c33452fbSAndroid Build Coastguard Worker
clean()387*c33452fbSAndroid Build Coastguard Worker void CElement::clean()
388*c33452fbSAndroid Build Coastguard Worker {
389*c33452fbSAndroid Build Coastguard Worker if (childrenAreDynamic()) {
390*c33452fbSAndroid Build Coastguard Worker
391*c33452fbSAndroid Build Coastguard Worker removeChildren();
392*c33452fbSAndroid Build Coastguard Worker } else {
393*c33452fbSAndroid Build Coastguard Worker // Just propagate
394*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
395*c33452fbSAndroid Build Coastguard Worker
396*c33452fbSAndroid Build Coastguard Worker pChild->clean();
397*c33452fbSAndroid Build Coastguard Worker }
398*c33452fbSAndroid Build Coastguard Worker }
399*c33452fbSAndroid Build Coastguard Worker }
400*c33452fbSAndroid Build Coastguard Worker
removeChildren()401*c33452fbSAndroid Build Coastguard Worker void CElement::removeChildren()
402*c33452fbSAndroid Build Coastguard Worker {
403*c33452fbSAndroid Build Coastguard Worker // Delete in reverse order
404*c33452fbSAndroid Build Coastguard Worker ChildArrayReverseIterator it;
405*c33452fbSAndroid Build Coastguard Worker
406*c33452fbSAndroid Build Coastguard Worker for (it = _childArray.rbegin(); it != _childArray.rend(); ++it) {
407*c33452fbSAndroid Build Coastguard Worker
408*c33452fbSAndroid Build Coastguard Worker delete *it;
409*c33452fbSAndroid Build Coastguard Worker }
410*c33452fbSAndroid Build Coastguard Worker _childArray.clear();
411*c33452fbSAndroid Build Coastguard Worker }
412*c33452fbSAndroid Build Coastguard Worker
findDescendant(CPathNavigator & pathNavigator) const413*c33452fbSAndroid Build Coastguard Worker const CElement *CElement::findDescendant(CPathNavigator &pathNavigator) const
414*c33452fbSAndroid Build Coastguard Worker {
415*c33452fbSAndroid Build Coastguard Worker string *pStrChildName = pathNavigator.next();
416*c33452fbSAndroid Build Coastguard Worker
417*c33452fbSAndroid Build Coastguard Worker if (!pStrChildName) {
418*c33452fbSAndroid Build Coastguard Worker
419*c33452fbSAndroid Build Coastguard Worker return this;
420*c33452fbSAndroid Build Coastguard Worker }
421*c33452fbSAndroid Build Coastguard Worker
422*c33452fbSAndroid Build Coastguard Worker const CElement *pChild = findChild(*pStrChildName);
423*c33452fbSAndroid Build Coastguard Worker
424*c33452fbSAndroid Build Coastguard Worker if (!pChild) {
425*c33452fbSAndroid Build Coastguard Worker
426*c33452fbSAndroid Build Coastguard Worker return nullptr;
427*c33452fbSAndroid Build Coastguard Worker }
428*c33452fbSAndroid Build Coastguard Worker
429*c33452fbSAndroid Build Coastguard Worker return pChild->findDescendant(pathNavigator);
430*c33452fbSAndroid Build Coastguard Worker }
431*c33452fbSAndroid Build Coastguard Worker
findDescendant(CPathNavigator & pathNavigator)432*c33452fbSAndroid Build Coastguard Worker CElement *CElement::findDescendant(CPathNavigator &pathNavigator)
433*c33452fbSAndroid Build Coastguard Worker {
434*c33452fbSAndroid Build Coastguard Worker string *pStrChildName = pathNavigator.next();
435*c33452fbSAndroid Build Coastguard Worker
436*c33452fbSAndroid Build Coastguard Worker if (!pStrChildName) {
437*c33452fbSAndroid Build Coastguard Worker
438*c33452fbSAndroid Build Coastguard Worker return this;
439*c33452fbSAndroid Build Coastguard Worker }
440*c33452fbSAndroid Build Coastguard Worker
441*c33452fbSAndroid Build Coastguard Worker CElement *pChild = findChild(*pStrChildName);
442*c33452fbSAndroid Build Coastguard Worker
443*c33452fbSAndroid Build Coastguard Worker if (!pChild) {
444*c33452fbSAndroid Build Coastguard Worker
445*c33452fbSAndroid Build Coastguard Worker return nullptr;
446*c33452fbSAndroid Build Coastguard Worker }
447*c33452fbSAndroid Build Coastguard Worker
448*c33452fbSAndroid Build Coastguard Worker return pChild->findDescendant(pathNavigator);
449*c33452fbSAndroid Build Coastguard Worker }
450*c33452fbSAndroid Build Coastguard Worker
isDescendantOf(const CElement * pCandidateAscendant) const451*c33452fbSAndroid Build Coastguard Worker bool CElement::isDescendantOf(const CElement *pCandidateAscendant) const
452*c33452fbSAndroid Build Coastguard Worker {
453*c33452fbSAndroid Build Coastguard Worker if (!_pParent) {
454*c33452fbSAndroid Build Coastguard Worker
455*c33452fbSAndroid Build Coastguard Worker return false;
456*c33452fbSAndroid Build Coastguard Worker }
457*c33452fbSAndroid Build Coastguard Worker if (_pParent == pCandidateAscendant) {
458*c33452fbSAndroid Build Coastguard Worker
459*c33452fbSAndroid Build Coastguard Worker return true;
460*c33452fbSAndroid Build Coastguard Worker }
461*c33452fbSAndroid Build Coastguard Worker return _pParent->isDescendantOf(pCandidateAscendant);
462*c33452fbSAndroid Build Coastguard Worker }
463*c33452fbSAndroid Build Coastguard Worker
findChild(const string & strName)464*c33452fbSAndroid Build Coastguard Worker CElement *CElement::findChild(const string &strName)
465*c33452fbSAndroid Build Coastguard Worker {
466*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
467*c33452fbSAndroid Build Coastguard Worker
468*c33452fbSAndroid Build Coastguard Worker if (pChild->getPathName() == strName) {
469*c33452fbSAndroid Build Coastguard Worker
470*c33452fbSAndroid Build Coastguard Worker return pChild;
471*c33452fbSAndroid Build Coastguard Worker }
472*c33452fbSAndroid Build Coastguard Worker }
473*c33452fbSAndroid Build Coastguard Worker
474*c33452fbSAndroid Build Coastguard Worker return nullptr;
475*c33452fbSAndroid Build Coastguard Worker }
476*c33452fbSAndroid Build Coastguard Worker
findChild(const string & strName) const477*c33452fbSAndroid Build Coastguard Worker const CElement *CElement::findChild(const string &strName) const
478*c33452fbSAndroid Build Coastguard Worker {
479*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
480*c33452fbSAndroid Build Coastguard Worker
481*c33452fbSAndroid Build Coastguard Worker if (pChild->getPathName() == strName) {
482*c33452fbSAndroid Build Coastguard Worker
483*c33452fbSAndroid Build Coastguard Worker return pChild;
484*c33452fbSAndroid Build Coastguard Worker }
485*c33452fbSAndroid Build Coastguard Worker }
486*c33452fbSAndroid Build Coastguard Worker
487*c33452fbSAndroid Build Coastguard Worker return nullptr;
488*c33452fbSAndroid Build Coastguard Worker }
489*c33452fbSAndroid Build Coastguard Worker
findChildOfKind(const string & strKind)490*c33452fbSAndroid Build Coastguard Worker CElement *CElement::findChildOfKind(const string &strKind)
491*c33452fbSAndroid Build Coastguard Worker {
492*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
493*c33452fbSAndroid Build Coastguard Worker
494*c33452fbSAndroid Build Coastguard Worker if (pChild->getKind() == strKind) {
495*c33452fbSAndroid Build Coastguard Worker
496*c33452fbSAndroid Build Coastguard Worker return pChild;
497*c33452fbSAndroid Build Coastguard Worker }
498*c33452fbSAndroid Build Coastguard Worker }
499*c33452fbSAndroid Build Coastguard Worker
500*c33452fbSAndroid Build Coastguard Worker return nullptr;
501*c33452fbSAndroid Build Coastguard Worker }
502*c33452fbSAndroid Build Coastguard Worker
findChildOfKind(const string & strKind) const503*c33452fbSAndroid Build Coastguard Worker const CElement *CElement::findChildOfKind(const string &strKind) const
504*c33452fbSAndroid Build Coastguard Worker {
505*c33452fbSAndroid Build Coastguard Worker for (CElement *pChild : _childArray) {
506*c33452fbSAndroid Build Coastguard Worker
507*c33452fbSAndroid Build Coastguard Worker if (pChild->getKind() == strKind) {
508*c33452fbSAndroid Build Coastguard Worker
509*c33452fbSAndroid Build Coastguard Worker return pChild;
510*c33452fbSAndroid Build Coastguard Worker }
511*c33452fbSAndroid Build Coastguard Worker }
512*c33452fbSAndroid Build Coastguard Worker
513*c33452fbSAndroid Build Coastguard Worker return nullptr;
514*c33452fbSAndroid Build Coastguard Worker }
515*c33452fbSAndroid Build Coastguard Worker
getPath() const516*c33452fbSAndroid Build Coastguard Worker string CElement::getPath() const
517*c33452fbSAndroid Build Coastguard Worker {
518*c33452fbSAndroid Build Coastguard Worker // Take out root element from the path
519*c33452fbSAndroid Build Coastguard Worker if (_pParent && _pParent->_pParent) {
520*c33452fbSAndroid Build Coastguard Worker
521*c33452fbSAndroid Build Coastguard Worker return _pParent->getPath() + "/" + getPathName();
522*c33452fbSAndroid Build Coastguard Worker }
523*c33452fbSAndroid Build Coastguard Worker return "/" + getPathName();
524*c33452fbSAndroid Build Coastguard Worker }
525*c33452fbSAndroid Build Coastguard Worker
getQualifiedPath() const526*c33452fbSAndroid Build Coastguard Worker string CElement::getQualifiedPath() const
527*c33452fbSAndroid Build Coastguard Worker {
528*c33452fbSAndroid Build Coastguard Worker return getPath() + " [" + getKind() + "]";
529*c33452fbSAndroid Build Coastguard Worker }
530*c33452fbSAndroid Build Coastguard Worker
getXmlElementName() const531*c33452fbSAndroid Build Coastguard Worker string CElement::getXmlElementName() const
532*c33452fbSAndroid Build Coastguard Worker {
533*c33452fbSAndroid Build Coastguard Worker // Default to element kind
534*c33452fbSAndroid Build Coastguard Worker return getKind();
535*c33452fbSAndroid Build Coastguard Worker }
536