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
31#pragma once
32#include "XmlElement.h"
33#include "XmlSerializingContext.h"
34
35#include "NonCopyable.hpp"
36
37#include <string>
38
39struct _xmlDoc;
40struct _xmlNode;
41struct _xmlError;
42
43/**
44  * The CXmlDocSource is used by CXmlDocSink.
45  * The interaction between the xml source and xml sink is defined
46  * in the process method of CXmlDocSink. One can subclass CXmlDocSource
47  * for different purposes by implementing the populate method and then
48  * use it with any existing implementation of CXmlDocSink.
49  */
50class CXmlDocSource : private utility::NonCopyable
51{
52public:
53    /**
54      * Constructor
55      *
56      * @param[out] pDoc a pointer to the xml document that will be filled by the class
57      * @param[in] pRootNode a pointer to the root element of the document.
58      * @param[in] bValidateWithSchema a boolean that toggles schema validation
59      */
60    CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema = false, _xmlNode *pRootNode = NULL);
61
62    /**
63      * Constructor
64      *
65      * @param[out] pDoc a pointer to the xml document that will be filled by the class
66      * @param[in] strRootElementType a string containing the root element type
67      * @param[in] strRootElementName a string containing the root element name
68      * @param[in] strNameAttributeName a string containing the name of the root name attribute
69      * @param[in] bValidateWithSchema a boolean that toggles schema validation
70      */
71    CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema,
72                  const std::string &strRootElementType = "",
73                  const std::string &strRootElementName = "",
74                  const std::string &strNameAttributeName = "");
75
76    /**
77      * Destructor
78      */
79    virtual ~CXmlDocSource();
80
81    /**
82      * Method called by the CXmlDocSink::process method.
83      *
84      * @param[out] serializingContext is used as error output
85      *
86      * @return false if there are any error
87      */
88    virtual bool populate(CXmlSerializingContext &serializingContext);
89
90    /**
91      * Method that returns the root element of the Xml tree.
92      *
93      * @param[out] xmlRootElement a reference to the CXmleElement destination
94      */
95    void getRootElement(CXmlElement &xmlRootElement) const;
96
97    /**
98      * Getter method.
99      *
100      * @return the root element's name
101      */
102    std::string getRootElementName() const;
103
104    /** Get the Schemas' base (folder) URI
105     */
106    std::string getSchemaBaseUri();
107
108    /** Set the Schema's base (folder) URI
109     *
110     * The schema for validating the XML document will be searched for in that
111     * folder.
112     *
113     * @param[in] uri The Schemas' base URI
114     */
115    void setSchemaBaseUri(const std::string &uri);
116
117    /**
118      * Getter method.
119      * Method that returns the root element's attribute with name matching strAttributeName.
120      *
121      * @param[in] strAttributeName is a std::string used to find the corresponding attribute
122      *
123      * @return the value of the root's attribute named as strAttributeName
124      */
125    std::string getRootElementAttributeString(const std::string &strAttributeName) const;
126
127    /**
128      * Getter method.
129      * Method that returns the xmlDoc contained in the Source.
130      * (Can be used in a Doc Sink)
131      *
132      * @return the document _pDoc
133      */
134    _xmlDoc *getDoc() const;
135
136    /**
137    * Method that checks that the xml document has been correctly parsed.
138    *
139    * @return false if any error occurs during the parsing
140    */
141    virtual bool isParsable() const;
142
143    /**
144     * Helper method to build final URI from base and relative uri/path
145     *
146     * base = "/path/to/file.xml"
147     *  - uri                   - returned value
148     *  .                       /path/to/
149     *  file.xsd                /path/to/file.xsd
150     *  ../from/file.xsd        /path/from/file.xsd
151     *  /path2/file.xsd         /path2/file.xsd
152     *
153     * @param[in] base uri, if base is directory, it must contains separator last
154     * @param[in] relative uri
155    *
156    * @return new made URI if succeeded relative input otherwise
157     */
158    static std::string mkUri(const std::string &base, const std::string &relative);
159
160    /**
161     * Helper method for creating an xml document from either a file or a
162     * string.
163     *
164     * @param[in] source either a filename or a string representing an xml document
165     * @param[in] fromFile true if source is a filename, false if source is an xml
166     *            represents an xml document
167     * @param[in] xincludes if true, process xincludes tags
168     * @param[in] serializingContext will receive any serialization error
169     */
170    static _xmlDoc *mkXmlDoc(const std::string &source, bool fromFile, bool xincludes,
171                             CXmlSerializingContext &serializingContext);
172
173protected:
174    /**
175      * Doc
176      */
177    _xmlDoc *_pDoc;
178
179    /**
180      * Root node
181      */
182    _xmlNode *_pRootNode;
183
184private:
185    /** Method that check the validity of the document with the xsd file.
186      *
187      * @return true if document is valid, false if any error occures
188      */
189    bool isInstanceDocumentValid();
190    std::string getSchemaUri() const;
191
192    /**
193      * Element type info
194      */
195    std::string _strRootElementType;
196
197    /**
198      * Element name info
199      */
200    std::string _strRootElementName;
201
202    /**
203      * Element name attribute info
204      */
205    std::string _strNameAttributeName;
206
207    /**
208      * Boolean that enables the validation via xsd files
209      */
210    bool _bValidateWithSchema;
211
212    std::string _schemaBaseUri;
213};
214