1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include "XMLObject.hxx"
17 #include "XMLValidation.hxx"
18 #include "XMLValidationSchema.hxx"
19 #include "XMLDocument.hxx"
20 #include "VariableScope.hxx"
21
22 extern "C"
23 {
24 #include "expandPathVariable.h"
25 #include "sci_malloc.h"
26 #include "localization.h"
27 #include "BOOL.h"
28 }
29
30 namespace org_modules_xml
31 {
32
XMLValidationSchema(const char * path,std::string * error)33 XMLValidationSchema::XMLValidationSchema(const char *path, std::string * error): XMLValidation()
34 {
35 char *expandedPath = expandPathVariable(const_cast < char *>(path));
36 if (expandedPath)
37 {
38 xmlSchemaParserCtxt *pctxt = xmlSchemaNewParserCtxt(expandedPath);
39 FREE(expandedPath);
40 if (!pctxt)
41 {
42 errorBuffer.clear();
43 errorBuffer.append(gettext("Cannot create a validation context"));
44 *error = errorBuffer;
45 }
46 else
47 {
48 validationFile = (void *)xmlSchemaParse(pctxt);
49 xmlSchemaFreeParserCtxt(pctxt);
50 if (!validationFile)
51 {
52 errorBuffer.clear();
53 errorBuffer.append(gettext("Cannot parse the schema"));
54 *error = errorBuffer;
55 }
56 else
57 {
58 openValidationFiles.push_back(this);
59 }
60 }
61 }
62 else
63 {
64 *error = std::string(gettext("Invalid file name: ")) + std::string(path);
65 }
66 scope->registerPointers(validationFile, this);
67 id = scope->getVariableId(*this);
68 }
69
~XMLValidationSchema()70 XMLValidationSchema::~XMLValidationSchema()
71 {
72 scope->unregisterPointer(validationFile);
73 scope->removeId(id);
74 if (validationFile)
75 {
76 xmlSchemaFree((xmlSchema *) validationFile);
77 openValidationFiles.remove(this);
78 if (openValidationFiles.size() == 0 && XMLDocument::getOpenDocuments().size() == 0)
79 {
80 resetScope();
81 }
82 }
83
84 errorBuffer.clear();
85 }
86
validate(const XMLDocument & doc,std::string * error) const87 bool XMLValidationSchema::validate(const XMLDocument & doc, std::string * error) const
88 {
89 bool ret;
90 xmlSchemaValidCtxt *vctxt = xmlSchemaNewValidCtxt((xmlSchema *) validationFile);
91
92 errorBuffer.clear();
93
94 if (!vctxt)
95 {
96 errorBuffer.append(gettext("Cannot create a validation context"));
97 *error = errorBuffer;
98 return false;
99 }
100
101 xmlSchemaSetValidErrors(vctxt, (xmlSchemaValidityErrorFunc) XMLValidation::errorFunction, 0, 0);
102
103 ret = BOOLtobool(xmlSchemaValidateDoc(vctxt, doc.getRealDocument()));
104
105 xmlSchemaSetValidErrors(vctxt, 0, 0, 0);
106 xmlSchemaFreeValidCtxt(vctxt);
107
108 if (ret)
109 {
110 *error = errorBuffer;
111 }
112
113 return ret == 0;
114 }
115
validate(xmlTextReader * reader,std::string * error) const116 bool XMLValidationSchema::validate(xmlTextReader * reader, std::string * error) const
117 {
118 xmlSchemaValidCtxt *vctxt = 0;
119 int last;
120 int valid;
121
122 errorBuffer.clear();
123
124 if (!reader)
125 {
126 errorBuffer.append(gettext("Cannot read the stream"));
127 *error = errorBuffer;
128 return false;
129 }
130
131 vctxt = xmlSchemaNewValidCtxt(getValidationFile < xmlSchema > ());
132 if (!vctxt)
133 {
134 errorBuffer.append(gettext("Cannot create a validation context"));
135 *error = errorBuffer;
136 return false;
137 }
138
139 xmlSchemaSetValidErrors(vctxt, (xmlSchemaValidityErrorFunc) XMLValidation::errorFunction, 0, 0);
140 xmlTextReaderSetErrorHandler(reader, (xmlTextReaderErrorFunc) XMLValidation::errorReaderFunction, 0);
141 xmlTextReaderSchemaValidateCtxt(reader, vctxt, 0);
142
143 while ((last = xmlTextReaderRead(reader)) == 1)
144 {
145 ;
146 }
147 valid = xmlTextReaderIsValid(reader);
148
149 xmlTextReaderSetErrorHandler(reader, 0, 0);
150 xmlSchemaSetValidErrors(vctxt, 0, 0, 0);
151 xmlFreeTextReader(reader);
152 xmlSchemaFreeValidCtxt(vctxt);
153
154 if (last == -1 || valid != 1)
155 {
156 *error = errorBuffer;
157 return false;
158 }
159
160 return true;
161 }
162
toString() const163 const std::string XMLValidationSchema::toString() const
164 {
165 std::ostringstream oss;
166 xmlSchema *schema = getValidationFile < xmlSchema > ();
167
168 oss << "XML Schema" << std::endl;
169 oss << "name: " << (schema->name ? (const char *)schema->name : "") << std::endl;
170 oss << "target namespace: " << (schema->targetNamespace ? (const char *)schema->targetNamespace : "") << std::endl;
171 oss << "version: " << (schema->version ? (const char *)schema->version : "");
172
173 return oss.str();
174 }
175
176 }
177
178