Add parser error handler.
authorNathan Letwory <nathan@letworyinteractive.com>
Mon, 5 Sep 2011 20:41:58 +0000 (20:41 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Mon, 5 Sep 2011 20:41:58 +0000 (20:41 +0000)
OpenCOLLADA is a validating parser, so is pretty strict about document form. The added error handler will print out any errors the parser finds. A pop-up will be shown too, advising the user to check the console for the error log.

source/blender/collada/CMakeLists.txt
source/blender/collada/DocumentImporter.cpp
source/blender/collada/ErrorHandler.cpp [new file with mode: 0644]
source/blender/collada/ErrorHandler.h [new file with mode: 0644]
source/blender/collada/collada.cpp
source/blender/windowmanager/intern/wm_operators.c

index ffe3d5f4f85afb53e1eae4d8a27392ddd68bfde6..d73373aa901b2817b332da90ae59e96049d49601 100644 (file)
@@ -51,6 +51,7 @@ set(SRC
        DocumentExporter.cpp
        DocumentImporter.cpp
        EffectExporter.cpp
+       ErrorHandler.cpp
        ExtraHandler.cpp
        ExtraTags.cpp
        GeometryExporter.cpp
@@ -74,6 +75,7 @@ set(SRC
        DocumentExporter.h
        DocumentImporter.h
        EffectExporter.h
+       ErrorHandler.h
        ExtraHandler.h
        ExtraTags.h
        GeometryExporter.h
index 586c6ccfe82804a2e5774de44208ab77d5732bc3..366837421e3173872b691808fdff7cd7d9d082d1 100644 (file)
@@ -76,6 +76,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "ExtraHandler.h"
+#include "ErrorHandler.h"
 #include "DocumentImporter.h"
 #include "TransformReader.h"
 
@@ -113,17 +114,19 @@ DocumentImporter::~DocumentImporter()
 
 bool DocumentImporter::import()
 {
-       /** TODO Add error handler (implement COLLADASaxFWL::IErrorHandler */
-       COLLADASaxFWL::Loader loader;
+       ErrorHandler errorHandler;
+       COLLADASaxFWL::Loader loader(&errorHandler);
        COLLADAFW::Root root(&loader, this);
        ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
        
        loader.registerExtraDataCallbackHandler(ehandler);
-       
 
        if (!root.loadDocument(mFilename))
                return false;
        
+       if(errorHandler.hasError())
+               return false;
+       
        /** TODO set up scene graph and such here */
        
        mImportStage = Controller;
diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp
new file mode 100644 (file)
index 0000000..7108dba
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Nathan Letwory.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/collada/ErrorHandler.cpp
+ *  \ingroup collada
+ */
+#include "ErrorHandler.h"
+#include <iostream>
+
+#include "COLLADASaxFWLIError.h"
+#include "COLLADASaxFWLSaxParserError.h"
+#include "COLLADASaxFWLSaxFWLError.h"
+
+#include "GeneratedSaxParserParserError.h"
+
+#include <string.h>
+
+//--------------------------------------------------------------------
+ErrorHandler::ErrorHandler() : mError(false)
+{
+}
+
+//--------------------------------------------------------------------
+ErrorHandler::~ErrorHandler()
+{
+}
+
+//--------------------------------------------------------------------
+bool ErrorHandler::handleError( const COLLADASaxFWL::IError* error )
+{
+       if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER )
+       {
+               COLLADASaxFWL::SaxParserError* saxParserError = (COLLADASaxFWL::SaxParserError*) error;
+               const GeneratedSaxParser::ParserError& parserError = saxParserError->getError();
+
+               // Workaround to avoid wrong error
+               if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED)
+               {
+                       if ( strcmp(parserError.getElement(), "effect") == 0 )
+                       {
+                               return false;
+                       }
+               }
+               if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT)
+               {
+                       if ( (strcmp(parserError.getElement(), "extra") == 0) 
+                               && (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0)) 
+                       {
+                               return false;
+                       }
+               }
+
+               if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE)
+               {
+                       std::cout << "Couldn't open file" << std::endl;
+                       mError = true;
+               }
+
+               std::cout << "Schema validation error: " << parserError.getErrorMessage() << std::endl;
+               mError = true;
+       }
+       else if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL )
+       {
+               COLLADASaxFWL::SaxFWLError* saxFWLError = (COLLADASaxFWL::SaxFWLError*) error;
+               std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl;
+               mError = true;
+       }
+       return false;
+}
diff --git a/source/blender/collada/ErrorHandler.h b/source/blender/collada/ErrorHandler.h
new file mode 100644 (file)
index 0000000..4064abb
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Nathan Letwory.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/collada/ErrorHandler.h
+ *  \ingroup collada
+ */
+
+#include <string>
+#include <map>
+#include <vector>
+#include <algorithm> // sort()
+
+#include "COLLADASaxFWLIErrorHandler.h"
+
+/** \brief Handler class for parser errors
+ */
+class ErrorHandler : public COLLADASaxFWL::IErrorHandler
+{
+public:
+       /** Constructor. */
+       ErrorHandler();
+
+       /** Destructor. */
+       virtual ~ErrorHandler();
+       /** handle any error thrown by the parser. */
+       bool virtual handleError(const COLLADASaxFWL::IError* error);
+       /** True if there was an error during parsing. */
+       bool hasError() { return mError; }
+private:
+       /** Disable default copy ctor. */
+       ErrorHandler( const ErrorHandler& pre );
+       /** Disable default assignment operator. */
+       const ErrorHandler& operator= ( const ErrorHandler& pre );
+       /** Hold error status. */
+       bool mError;
+};
+
index c15e608c3603deb2acdefc1d548b0af4e74f9442..4caca20531f9073f2af4c481bbcdbe77a5476eb4 100644 (file)
@@ -46,9 +46,9 @@ extern "C"
        int collada_import(bContext *C, const char *filepath)
        {
                DocumentImporter imp (C, filepath);
-               imp.import();
+               if(imp.import()) return 1;
 
-               return 1;
+               return 0;
        }
 
        int collada_export(Scene *sce, const char *filepath, int selected)
index 0e0203543a4c3258bc3106a915234f4c9554ed10..68a4eebf93f26b3829178094a8dd29d5810276a5 100644 (file)
@@ -2082,7 +2082,9 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
        }
 
        RNA_string_get(op->ptr, "filepath", filename);
-       collada_import(C, filename);
+       if(collada_import(C, filename)) return OPERATOR_FINISHED;
+       
+       BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document. Please see console for error log.");
        
        return OPERATOR_FINISHED;
 }