blob: 144b6362da9b14f930558b965346e4d78172cc15 [file] [log] [blame]
Georges-Henri Baron326a31d2012-06-28 12:05:09 +02001/*
Patrick Benavoli68a91282011-08-31 11:23:23 +02002 * INTEL CONFIDENTIAL
Georges-Henri Baroncec86c12012-09-04 17:30:28 +02003 * Copyright © 2013 Intel
Patrick Benavoli68a91282011-08-31 11:23:23 +02004 * Corporation All Rights Reserved.
Georges-Henri Baron326a31d2012-06-28 12:05:09 +02005 *
Patrick Benavoli68a91282011-08-31 11:23:23 +02006 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material contains trade secrets and proprietary
10 * and confidential information of Intel or its suppliers and licensors. The
11 * Material is protected by worldwide copyright and trade secret laws and
12 * treaty provisions. No part of the Material may be used, copied, reproduced,
13 * modified, published, uploaded, posted, transmitted, distributed, or
14 * disclosed in any way without Intel’s prior express written permission.
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020015 *
Patrick Benavoli68a91282011-08-31 11:23:23 +020016 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Intel in writing.
Patrick Benavoli68a91282011-08-31 11:23:23 +020021 */
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020022
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020023#include "XmlDocSource.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020024#include <libxml/tree.h>
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020025#include <libxml/xmlschemas.h>
Patrick Benavoli68a91282011-08-31 11:23:23 +020026#include <stdlib.h>
27
28// Schedule for libxml2 library
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020029bool CXmlDocSource::_bLibXml2CleanupScheduled;
Patrick Benavoli68a91282011-08-31 11:23:23 +020030
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020031CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc, _xmlNode *pRootNode):
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020032 _pDoc(pDoc),
33 _pRootNode(pRootNode),
34 _strXmlSchemaFile(""),
35 _strRootElementType(""),
36 _strRootElementName(""),
37 _strNameAttrituteName(""),
38 _bNameCheck(false)
Patrick Benavoli68a91282011-08-31 11:23:23 +020039{
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020040 init();
41}
Patrick Benavoli68a91282011-08-31 11:23:23 +020042
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020043CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc,
44 const string& strXmlSchemaFile,
45 const string& strRootElementType,
46 const string& strRootElementName,
47 const string& strNameAttrituteName) :
48 _pDoc(pDoc),
49 _pRootNode(NULL),
50 _strXmlSchemaFile(strXmlSchemaFile),
51 _strRootElementType(strRootElementType),
52 _strRootElementName(strRootElementName),
53 _strNameAttrituteName(strNameAttrituteName),
54 _bNameCheck(true)
55{
56 init();
57}
Patrick Benavoli68a91282011-08-31 11:23:23 +020058
Georges-Henri Baroncec86c12012-09-04 17:30:28 +020059CXmlDocSource::CXmlDocSource(_xmlDoc* pDoc,
60 const string& strXmlSchemaFile,
61 const string& strRootElementType) :
62 _pDoc(pDoc), _pRootNode(NULL),
63 _strXmlSchemaFile(strXmlSchemaFile),
64 _strRootElementType(strRootElementType),
65 _strRootElementName(""),
66 _strNameAttrituteName(""),
67 _bNameCheck(false)
68{
69 init();
Patrick Benavoli68a91282011-08-31 11:23:23 +020070}
71
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020072CXmlDocSource::~CXmlDocSource()
Patrick Benavoli68a91282011-08-31 11:23:23 +020073{
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020074 if (_pDoc) {
75 // Free XML doc
76 xmlFreeDoc(_pDoc);
77 _pDoc = NULL;
78 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020079}
80
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020081void CXmlDocSource::getRootElement(CXmlElement& xmlRootElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020082{
83 xmlRootElement.setXmlElement(_pRootNode);
84}
85
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020086string CXmlDocSource::getRootElementName() const
Patrick Benavoli68a91282011-08-31 11:23:23 +020087{
88 return (const char*)_pRootNode->name;
89}
90
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020091string CXmlDocSource::getRootElementAttributeString(const string& strAttributeName) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020092{
93 CXmlElement topMostElement(_pRootNode);
94
95 return topMostElement.getAttributeString(strAttributeName);
96}
97
Georges-Henri Baron326a31d2012-06-28 12:05:09 +020098_xmlDoc* CXmlDocSource::getDoc() const
99{
100 return _pDoc;
101}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200102
Georges-Henri Baroncec86c12012-09-04 17:30:28 +0200103bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext)
104{
105 // Check that the doc has been created
106 if (!_pDoc) {
107
108 serializingContext.setError("Could not parse document ");
109
110 return false;
111 }
112
113 // Validate
114 if (!isInstanceDocumentValid()) {
115
116 serializingContext.setError("Document is not valid");
117
118 return false;
119 }
120
121 // Check Root element type
122 if (getRootElementName() != _strRootElementType) {
123
124 serializingContext.setError("Error: Wrong XML structure document ");
125 serializingContext.appendLineToError("Root Element " + getRootElementName()
126 + " mismatches expected type " + _strRootElementType);
127
128 return false;
129 }
130
131 if (_bNameCheck) {
132
133 string strRootElementNameCheck = getRootElementAttributeString(_strNameAttrituteName);
134
135 // Check Root element name attribute (if any)
136 if (!_strRootElementName.empty() && strRootElementNameCheck != _strRootElementName) {
137
138 serializingContext.setError("Error: Wrong XML structure document ");
139 serializingContext.appendLineToError(_strRootElementType + " element "
140 + _strRootElementName + " mismatches expected "
141 + _strRootElementType + " type "
142 + strRootElementNameCheck);
143
144 return false;
145 }
146 }
147
148 return true;
149}
150
151void CXmlDocSource::init()
152{
153 if (!_bLibXml2CleanupScheduled) {
154
155 // Schedule cleanup
156 atexit(xmlCleanupParser);
157
158 _bLibXml2CleanupScheduled = true;
159 }
160
161 if (!_pRootNode) {
162
163 _pRootNode = xmlDocGetRootElement(_pDoc);
164 }
165}
166
167bool CXmlDocSource::isInstanceDocumentValid()
168{
169#ifdef LIBXML_SCHEMAS_ENABLED
170 xmlDocPtr pSchemaDoc = xmlReadFile(_strXmlSchemaFile.c_str(), NULL, XML_PARSE_NONET);
171
172 if (!pSchemaDoc) {
173 // Unable to load Schema
174 return false;
175 }
176
177 xmlSchemaParserCtxtPtr pParserCtxt = xmlSchemaNewDocParserCtxt(pSchemaDoc);
178
179 if (!pParserCtxt) {
180
181 // Unable to create schema context
182 xmlFreeDoc(pSchemaDoc);
183 return false;
184 }
185
186 // Get Schema
187 xmlSchemaPtr pSchema = xmlSchemaParse(pParserCtxt);
188
189 if (!pSchema) {
190
191 // Invalid Schema
192 xmlSchemaFreeParserCtxt(pParserCtxt);
193 xmlFreeDoc(pSchemaDoc);
194 return false;
195 }
196 xmlSchemaValidCtxtPtr pValidationCtxt = xmlSchemaNewValidCtxt(pSchema);
197
198 if (!pValidationCtxt) {
199
200 // Unable to create validation context
201 xmlSchemaFree(pSchema);
202 xmlSchemaFreeParserCtxt(pParserCtxt);
203 xmlFreeDoc(pSchemaDoc);
204 return false;
205 }
206
207 xmlSetStructuredErrorFunc(this, schemaValidityStructuredErrorFunc);
208
209 bool isDocValid = xmlSchemaValidateDoc(pValidationCtxt, _pDoc) == 0;
210
211 xmlSchemaFreeValidCtxt(pValidationCtxt);
212 xmlSchemaFree(pSchema);
213 xmlSchemaFreeParserCtxt(pParserCtxt);
214 xmlFreeDoc(pSchemaDoc);
215
216 return isDocValid;
217#else
218 return true;
219#endif
220}
221
222void CXmlDocSource::schemaValidityStructuredErrorFunc(void* pUserData, _xmlError* pError)
223{
224 (void)pUserData;
225
226#ifdef LIBXML_SCHEMAS_ENABLED
227 // Display message
228 puts(pError->message);
229#endif
230}