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 
39 struct _xmlDoc;
40 struct _xmlNode;
41 struct _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   */
50 class CXmlDocSource : private utility::NonCopyable
51 {
52 public:
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 
173 protected:
174     /**
175       * Doc
176       */
177     _xmlDoc *_pDoc;
178 
179     /**
180       * Root node
181       */
182     _xmlNode *_pRootNode;
183 
184 private:
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