Browse Source

improve json validation

Kolja Strohm 7 months ago
parent
commit
b384eb1213
2 changed files with 128 additions and 50 deletions
  1. 110 33
      JSON.cpp
  2. 18 17
      JSON.h

+ 110 - 33
JSON.cpp

@@ -683,13 +683,16 @@ void JSONTypeMissmatch::printInvalidInfo(int indent) const
     std::cout << ind.getText() << "Type missmatch at path '" << path.getText()
               << "'. JSON Value\n"
               << ind.getText() << foundValue->toString().getText() << "\n"
-              << ind.getText() << "does not match type\n"
-              << ind.getText() << expected->toString().getText() << "\n";
+              << ind.getText() << "does not match expected type\n";
     if (reason)
     {
         std::cout << ind.getText() << "Reason for type mismatch:\n";
         reason->printInvalidInfo(indent + 4);
     }
+    else
+    {
+        std::cout << ind.getText() << expected->toString().getText() << "\n";
+    }
 }
 
 JSONValue* JSONTypeMissmatch::getValidPart(
@@ -709,6 +712,23 @@ JSONValue* JSONTypeMissmatch::getValidPart(
             {
                 if (removedPartsValidationResults)
                 {
+                    if (temporaryInvalidParts.getEintragAnzahl() == 1)
+                    {
+                        if (reason) reason->release();
+                        reason = temporaryInvalidParts.get(0);
+                    }
+                    else
+                    {
+                        for (JSONValidationResult* res : temporaryInvalidParts)
+                        {
+                            if (res->isDifferent(this))
+                            {
+                                removedPartsValidationResults->add(
+                                    dynamic_cast<JSONValidationResult*>(
+                                        res->getThis()));
+                            }
+                        }
+                    }
                     removedPartsValidationResults->add(
                         dynamic_cast<JSONValidationResult*>(getThis()));
                 }
@@ -739,13 +759,14 @@ JSONValue* JSONTypeMissmatch::getValidPart(
                     JSONValidationResult* res = JSONValidator(
                         dynamic_cast<XML::Element*>(expected->getThis()))
                                                     .validate(tmp);
+                    res->addBasePath(path);
                     if (res->isValid())
                     {
                         res->release();
                         p->release();
                         return tmp;
                     }
-                    else if (res->isDifferent(this, path) || !valid)
+                    else if (res->isDifferent(this) || !valid)
                     {
                         p->release();
                         tmp->release();
@@ -768,6 +789,23 @@ JSONValue* JSONTypeMissmatch::getValidPart(
             {
                 if (removedPartsValidationResults)
                 {
+                    if (temporaryInvalidParts.getEintragAnzahl() == 1)
+                    {
+                        if (reason) reason->release();
+                        reason = temporaryInvalidParts.get(0);
+                    }
+                    else
+                    {
+                        for (JSONValidationResult* res : temporaryInvalidParts)
+                        {
+                            if (res->isDifferent(this))
+                            {
+                                removedPartsValidationResults->add(
+                                    dynamic_cast<JSONValidationResult*>(
+                                        res->getThis()));
+                            }
+                        }
+                    }
                     removedPartsValidationResults->add(
                         dynamic_cast<JSONValidationResult*>(getThis()));
                 }
@@ -794,13 +832,14 @@ JSONValue* JSONTypeMissmatch::getValidPart(
                 JSONValidationResult* res = JSONValidator(
                     dynamic_cast<XML::Element*>(expected->getThis()))
                                                 .validate(tmp);
+                res->addBasePath(path);
                 if (res->isValid())
                 {
                     res->release();
                     p->release();
                     return tmp;
                 }
-                else if (res->isDifferent(this, path) || !valid)
+                else if (res->isDifferent(this) || !valid)
                 {
                     p->release();
                     tmp->release();
@@ -829,14 +868,19 @@ Text JSONTypeMissmatch::getPath() const
     return path;
 }
 
-bool JSONTypeMissmatch::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONTypeMissmatch::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONTypeMissmatch* casted
         = dynamic_cast<const JSONTypeMissmatch*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
-    return reason->isDifferent(casted->reason, path);
+    if (!casted->getPath().istGleich(path)) return 1;
+    return reason->isDifferent(casted->reason);
+}
+
+void Framework::JSON::Validator::JSONTypeMissmatch::addBasePath(Text basePath)
+{
+    path = basePath + path;
+    if (reason) reason->addBasePath(basePath);
 }
 
 #pragma endregion Content
@@ -885,16 +929,20 @@ Text JSONUnknownValue::getPath() const
     return path;
 }
 
-bool JSONUnknownValue::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONUnknownValue::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONUnknownValue* casted
         = dynamic_cast<const JSONUnknownValue*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
+    if (!casted->getPath().istGleich(path)) return 1;
     return 0;
 }
 
+void Framework::JSON::Validator::JSONUnknownValue::addBasePath(Text basePath)
+{
+    path = basePath + path;
+}
+
 #pragma endregion Content
 
 #pragma region JSONMissingValue
@@ -935,12 +983,13 @@ JSONValue* JSONMissingValue::getValidPart(
         JSONValidationResult* res
             = JSONValidator(dynamic_cast<XML::Element*>(expected->getThis()))
                   .validate(def);
+        res->addBasePath(path);
         if (res->isValid())
         {
             res->release();
             return def;
         }
-        else if (res->isDifferent(this, path))
+        else if (res->isDifferent(this))
         {
             def->release();
             JSONValue* result
@@ -963,16 +1012,20 @@ Text JSONMissingValue::getPath() const
     return path;
 }
 
-bool JSONMissingValue::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONMissingValue::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONMissingValue* casted
         = dynamic_cast<const JSONMissingValue*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
+    if (!casted->getPath().istGleich(path)) return 1;
     return 0;
 }
 
+void Framework::JSON::Validator::JSONMissingValue::addBasePath(Text basePath)
+{
+    path = basePath + path;
+}
+
 #pragma endregion Content
 
 #pragma region JSONMissingOneOf
@@ -997,7 +1050,7 @@ void JSONMissingOneOf::printInvalidInfo(int indent) const
     Text ind = "";
     ind.fillText(' ', indent);
     std::cout << ind.getText() << "Missing Value at '" << path.getText()
-              << "'. The value should have one of the following types:\n";
+              << "'. The value should have one of the specified types:\n";
     ind += "    ";
     for (XML::Element* e : expected)
     {
@@ -1022,16 +1075,20 @@ Text JSONMissingOneOf::getPath() const
     return path;
 }
 
-bool JSONMissingOneOf::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONMissingOneOf::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONMissingOneOf* casted
         = dynamic_cast<const JSONMissingOneOf*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
+    if (!casted->getPath().istGleich(path)) return 1;
     return 0;
 }
 
+void Framework::JSON::Validator::JSONMissingOneOf::addBasePath(Text basePath)
+{
+    path = basePath + path;
+}
+
 #pragma endregion Content
 
 #pragma region JSONNoTypeMatching
@@ -1063,13 +1120,8 @@ void JSONNoTypeMatching::printInvalidInfo(int indent) const
     Text ind = "";
     ind.fillText(' ', indent);
     std::cout << ind.getText() << "Found Value at '" << path.getText()
-              << "' did not match any of the given possible types:\n";
+              << "' did not match any of the specified types\n";
     Text ind2 = ind + "    ";
-    for (XML::Element* element : expected)
-    {
-        std::cout << ind2.getText() << element->toString().getText() << "\n";
-    }
-
     std::cout << ind.getText() << "Reasons:\n";
     for (JSONValidationResult* reason : reasons)
     {
@@ -1080,10 +1132,24 @@ void JSONNoTypeMatching::printInvalidInfo(int indent) const
 JSONValue* JSONNoTypeMatching::getValidPart(
     RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
+    RCArray<JSONValidationResult> tempErrors;
+    for (JSONValidationResult* reason : reasons)
+    {
+        JSONValue *result = reason->getValidPart(&tempErrors);
+        if (result)
+        {
+			return result;
+		}
+    }
     if (removedPartsValidationResults)
     {
         removedPartsValidationResults->add(
             dynamic_cast<JSONValidationResult*>(getThis()));
+        reasons.leeren();
+        for (JSONValidationResult* error : tempErrors)
+        {
+            reasons.add(error);
+        }
     }
     // multiple possibilities are undecidable
     return 0;
@@ -1094,21 +1160,28 @@ Text JSONNoTypeMatching::getPath() const
     return path;
 }
 
-bool JSONNoTypeMatching::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONNoTypeMatching::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONNoTypeMatching* casted
         = dynamic_cast<const JSONNoTypeMatching*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
+    if (!casted->getPath().istGleich(path)) return 1;
     for (int i = 0; i < reasons.getEintragAnzahl(); i++)
     {
-        if (reasons.z(i)->isDifferent(casted->reasons.z(i), additionalPath))
-            return 1;
+        if (reasons.z(i)->isDifferent(casted->reasons.z(i))) return 1;
     }
     return 0;
 }
 
+void Framework::JSON::Validator::JSONNoTypeMatching::addBasePath(Text basePath)
+{
+    path = basePath + path;
+    for (JSONValidationResult* reason : reasons)
+    {
+        reason->addBasePath(basePath);
+    }
+}
+
 #pragma endregion Content
 
 #pragma region JSONValidValue
@@ -1143,15 +1216,19 @@ Text JSONValidValue::getPath() const
     return path;
 }
 
-bool JSONValidValue::isDifferent(
-    const JSONValidationResult* zResult, Text additionalPath) const
+bool JSONValidValue::isDifferent(const JSONValidationResult* zResult) const
 {
     const JSONValidValue* casted = dynamic_cast<const JSONValidValue*>(zResult);
     if (casted == 0) return 1;
-    if (!casted->getPath().istGleich(additionalPath + path)) return 1;
+    if (!casted->getPath().istGleich(path)) return 1;
     return 0;
 }
 
+void Framework::JSON::Validator::JSONValidValue::addBasePath(Text basePath)
+{
+    path = basePath + path;
+}
+
 #pragma endregion Content
 
 #pragma endregion Content

+ 18 - 17
JSON.h

@@ -253,8 +253,8 @@ namespace Framework
                         zRemovedPartsValidationResults)
                     = 0;
                 virtual Text getPath() const = 0;
-                virtual bool isDifferent(const JSONValidationResult* zResult,
-                    Text additionalPath) const
+                virtual void addBasePath(Text basePath) = 0;
+                virtual bool isDifferent(const JSONValidationResult* zResult) const
                     = 0;
             };
 
@@ -279,8 +279,9 @@ namespace Framework
                     RCArray<JSONValidationResult>*
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
-                bool isDifferent(const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                __declspec(dllexport) bool isDifferent(
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             class JSONUnknownValue : public JSONValidationResult
@@ -301,8 +302,8 @@ namespace Framework
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
-                    const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             class JSONMissingValue : public JSONValidationResult
@@ -323,8 +324,8 @@ namespace Framework
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
-                    const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             class JSONMissingOneOf : public JSONValidationResult
@@ -345,8 +346,8 @@ namespace Framework
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
-                    const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             class JSONNoTypeMatching : public JSONValidationResult
@@ -371,8 +372,8 @@ namespace Framework
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
-                    const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             class JSONValidValue : public JSONValidationResult
@@ -393,8 +394,8 @@ namespace Framework
                         zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
-                    const JSONValidationResult* zResult,
-                    Text additionalPath) const override;
+                    const JSONValidationResult* zResult) const override;
+                __declspec(dllexport) void addBasePath(Text basePath) override;
             };
 
             template<typename T> class StringValidationBuilder;
@@ -878,9 +879,9 @@ namespace Framework
 
                 ObjectValidationBuilder<T>* allowAdditionalAttriutes()
                 {
-					element.setAttribute("allowAdditionalAttributes", "true");
-					return this;
-				}
+                    element.setAttribute("allowAdditionalAttributes", "true");
+                    return this;
+                }
 
                 T* finishObject()
                 {