1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup collada
19  */
20 #include "ErrorHandler.h"
21 #include <iostream>
22 
23 #include "COLLADASaxFWLIError.h"
24 #include "COLLADASaxFWLSaxFWLError.h"
25 #include "COLLADASaxFWLSaxParserError.h"
26 
27 #include "GeneratedSaxParserParserError.h"
28 
29 #include <string.h>
30 
31 #include "BLI_utildefines.h"
32 
33 //--------------------------------------------------------------------
ErrorHandler()34 ErrorHandler::ErrorHandler() : mError(false)
35 {
36 }
37 
38 //--------------------------------------------------------------------
~ErrorHandler()39 ErrorHandler::~ErrorHandler()
40 {
41 }
42 
43 //--------------------------------------------------------------------
handleError(const COLLADASaxFWL::IError * error)44 bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
45 {
46   /* This method must return false when Collada should continue.
47    * See https://github.com/KhronosGroup/OpenCOLLADA/issues/442
48    */
49   bool isError = true;
50   std::string error_context;
51   std::string error_message;
52 
53   if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
54     error_context = "Schema validation";
55 
56     COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *)error;
57     const GeneratedSaxParser::ParserError &parserError = saxParserError->getError();
58     error_message = parserError.getErrorMessage();
59 
60     if (parserError.getErrorType() ==
61         GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) {
62       if (STREQ(parserError.getElement(), "effect")) {
63         isError = false;
64       }
65     }
66 
67     else if (parserError.getErrorType() ==
68              GeneratedSaxParser::ParserError::
69                  ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) {
70       if (!(STREQ(parserError.getElement(), "extra") &&
71             STREQ(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract"))) {
72         isError = false;
73       }
74     }
75 
76     else if (parserError.getErrorType() ==
77              GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) {
78       isError = true;
79       error_context = "File access";
80     }
81 
82     else if (parserError.getErrorType() ==
83              GeneratedSaxParser::ParserError::ERROR_REQUIRED_ATTRIBUTE_MISSING) {
84       isError = true;
85     }
86 
87     else {
88       isError = (parserError.getSeverity() !=
89                  GeneratedSaxParser::ParserError::Severity::SEVERITY_ERROR_NONCRITICAL);
90     }
91   }
92   else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) {
93     error_context = "Sax FWL";
94     COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *)error;
95     error_message = saxFWLError->getErrorMessage();
96 
97     /*
98      * Accept non critical errors as warnings (i.e. texture not found)
99      * This makes the importer more graceful, so it now imports what makes sense.
100      */
101 
102     isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL);
103   }
104   else {
105     error_context = "OpenCollada";
106     error_message = error->getFullErrorMessage();
107     isError = true;
108   }
109 
110   std::string severity = (isError) ? "Error" : "Warning";
111   std::cout << error_context << " (" << severity << "): " << error_message << std::endl;
112   if (isError) {
113     std::cout << "The Collada import has been forced to stop." << std::endl;
114     std::cout << "Please fix the reported error and then try again.";
115     mError = true;
116   }
117   return isError;
118 }
119