fw4spl
Validator.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2015.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 //#include <ios_base.h> not necessary on win32
8 #include <boost/filesystem/operations.hpp>
9 #include <libxml/xmlversion.h>
10 #ifndef LIBXML_SCHEMAS_ENABLED
11  #warning "Error libxml schemas disabled"
12 #endif
13 #include <libxml/tree.h>
14 #include <libxml/parser.h>
15 #include <libxml/xinclude.h>
16 #include <libxml/xmlschemas.h>
17 #include <libxml/xmlschemastypes.h>
18 
19 #include "fwRuntime/RuntimeException.hpp"
20 #include "fwRuntime/io/Validator.hpp"
21 
22 #include <fwCore/base.hpp>
23 
24 namespace fwRuntime
25 {
26 namespace io
27 {
28 
29 //------------------------------------------------------------------------------
30 
31 Validator::Validator( const Validator &validator )
32 {
33  m_xsd_content = validator.m_xsd_content;
34  m_schemaParserContext = validator.m_schemaParserContext;
35  m_schema = validator.m_schema;
36 }
37 
38 //------------------------------------------------------------------------------
39 
40 Validator::Validator( const std::string & buffer )
41 {
42  m_xsd_content = buffer;
43 }
44 
45 //------------------------------------------------------------------------------
46 
47 Validator::Validator( const boost::filesystem::path & path )
48 {
49  std::string strPath( path.string() );
50  // Checks the path validity.
51  if( ::boost::filesystem::exists(path) == false || ::boost::filesystem::is_directory(path) )
52  {
53  throw RuntimeException( strPath + ": is not a valid path to an xml schema file." );
54  }
55  m_xsd_content = strPath;
56 }
57 
58 //------------------------------------------------------------------------------
59 
61 {
62 }
63 
64 //------------------------------------------------------------------------------
65 
67 {
68  m_errorLog.str( std::string() );
69 }
70 
71 //------------------------------------------------------------------------------
72 
73 const std::string Validator::getErrorLog() const
74 {
75  return m_errorLog.str();
76 }
77 
78 //------------------------------------------------------------------------------
79 
80 void Validator::initializeContext()
81 {
82  if(m_schemaValidContext)
83  {
84  return;
85  }
86 
87  if ( !m_schemaParserContext )
88  {
89  if (!(m_schemaParserContext = SchemaParserCtxtSptr (
90  xmlSchemaNewParserCtxt(m_xsd_content.c_str()),
91  xmlSchemaFreeParserCtxt)
92  ) )
93  {
94  return;
95  }
96  // Set the structured error callback
97  xmlSchemaSetParserStructuredErrors(m_schemaParserContext.get(), Validator::ErrorHandler, this );
98  }
99 
100  // Load XML schema content
101  if (!m_schema)
102  {
103  m_schema = SchemaSptr ( xmlSchemaParse(m_schemaParserContext.get()), xmlSchemaFree );
104  }
105  if (!m_schema)
106  {
107  return;
108  }
109 
110  // Create XML schemas validation context
111  if ( (m_schemaValidContext = SchemaValidCtxtSptr( xmlSchemaNewValidCtxt(m_schema.get()), xmlSchemaFreeValidCtxt)) )
112  {
113  // Set the structured error callback
114  xmlSchemaSetValidStructuredErrors( m_schemaValidContext.get(), Validator::ErrorHandler, this );
115  }
116 }
117 
118 //------------------------------------------------------------------------------
119 
120 bool Validator::validate( const boost::filesystem::path & xmlFile )
121 {
122  int result;
123 
124  initializeContext();
125 
126  xmlDocPtr xmlDoc = xmlParseFile ( xmlFile.string().c_str () );
127  if (xmlDoc == NULL)
128  {
129  throw std::ios_base::failure("Unable to parse the XML file " + xmlFile.string() );
130  }
131  xmlNodePtr xmlRoot = xmlDocGetRootElement (xmlDoc);
132  if (xmlXIncludeProcessTreeFlags (xmlRoot,XML_PARSE_NOBASEFIX) == -1)
133  {
134  xmlFreeDoc(xmlDoc);
135  throw std::ios_base::failure(std::string ("Unable to manage xinclude !"));
136  }
137 
138  if(!m_schemaValidContext)
139  {
140  return false;
141  }
142 
143  result = xmlSchemaValidateDoc(m_schemaValidContext.get(), xmlDoc );
144 
145  xmlFreeDoc(xmlDoc);
146 
147  if ( result !=0 )
148  {
149  OSLM_WARN("Validator::validation NOK, xml = " << xmlFile.string() );
150  OSLM_WARN("Validator::validation NOK, xsd = " << getXsdContent() );
151  OSLM_ERROR("Validator::validation NOK, error log = " << getErrorLog() );
152  }
153 
154  return result == 0;
155 }
156 
157 //------------------------------------------------------------------------------
158 
159 bool Validator::validate( xmlNodePtr node )
160 {
161  int result;
162 
163  initializeContext();
164 
165  if(!m_schemaValidContext)
166  {
167  return false;
168  }
169 
170  result = xmlSchemaValidateOneElement( m_schemaValidContext.get(), node );
171 
172  if ( result !=0 )
173  {
174  xmlBufferPtr buffer = xmlBufferCreate();
175  xmlNodeDump( buffer, node->doc, node, 1, 1 );
176  OSLM_WARN("Validator::validation NOK, node :\n " << buffer->content);
177  xmlBufferFree( buffer );
178  OSLM_WARN("Validator::validation NOK, xsd = " << getXsdContent() );
179  OSLM_ERROR("Validator::validation NOK, error log = " << getErrorLog() );
180  }
181 
182  return result == 0;
183 }
184 
185 //------------------------------------------------------------------------------
186 
187 void Validator::ErrorHandler( void * userData, xmlErrorPtr error )
188 {
189  Validator * validator = (Validator*) userData;
190 
191  validator->m_errorLog << "At line " << error->line << ": " << error->message;
192 }
193 
194 //------------------------------------------------------------------------------
195 
197 {
198  return m_xsd_content;
199 }
200 
201 //------------------------------------------------------------------------------
202 
203 } // namespace io
204 
205 } // namespace fwRuntime
Defines the runtime exception class.
void clearErrorLog()
Clears the error log.
Definition: Validator.cpp:66
FWRUNTIME_API const std::string getErrorLog() const
Retrieves the error log content.
Definition: Validator.cpp:73
FWRUNTIME_API bool validate(const boost::filesystem::path &xmlFile)
Validates the given file.
Definition: Validator.cpp:120
The namespace fwRuntime contains classes to manage bundle, configuration element, extension point in ...
#define OSLM_ERROR(message)
Definition: spyLog.hpp:274
#define OSLM_WARN(message)
Definition: spyLog.hpp:263
Implements an XML validator.
Definition: Validator.hpp:37
FWRUNTIME_API Validator(const Validator &validator)
Copy Constructor.
Definition: Validator.cpp:31
FWRUNTIME_API ~Validator()
Destructor.
Definition: Validator.cpp:60
FWRUNTIME_API std::string getXsdContent()
Returns the xsd content in string format.
Definition: Validator.cpp:196