Skip to content

Validation messages

fge edited this page Aug 29, 2012 · 12 revisions

Introduction

Purpose

This page describes the current status of the validation message "API" as it currently stands in the implementation.

This page exists for two reasons:

  • the API is there, but there is no Javadoc for it;
  • I ask for ideas.

Overview

There are three classes implied:

  • ValidationReport: as its name says;
  • ValidationMessage, an individual message of a validation report;
  • ValidationDomain: what validation domain does this message apply to (see below).

For the recall, a ValidationReport is what you get out of a single instance validation using a JsonSchema instance. Prior to this development, all messages you put into a validation report were plain strings (and not very informative as that). But now, all this has changed.

NOTE to existing users: the .getMessages() method still exists, and still returns a list of strings; but they are much more verbose than before.

NOTE to existing keyword implementors: read below, you cannot just stuff a plain string into a report anymore.

Anatomy of a validation message

As mentioned above, the class used for this is ValidationMessage. You cannot instantiate one directly but have to use its builtin builder class (yeah, I am probably overusing this pattern).

Mandatory fields

A message has three fields which must be set:

  • The validation domain. Four validation domains are defined: ref resolving, syntax validation, instance validation and unknown. It is of course discouraged to use the latter -- and the first of them is only really useful for $ref, but it is a critical part which deserved its own domain.
  • The associated keyword. This is a justification for the above, basically: for instance, you have a schema with a dependencies keyword; if there is a syntax error for that keyword in your schema, the domain will be syntax validation; if an instance fails to validate against an existing dependencies keyword entry, the domain will be instance validation.
  • The associated message. Of course, you want to explicitly tell why this message was there in the first place, right?

So, there. The validation domain is set by the builder constructor, you don't have a choice (the argument is a ValidationDomain enum value). You set the associated keyword using .setKeyword() and the message using .setMessage(). Any missing required field will yield a NullPointerException when you try to .build() the message!

Further information

Now, you can of course add further information to the message, and are in fact strongly advised to do so. For this, the method to use (on the builder, always) is .addInfo(). Its first argument is always a String. The second argument can be, in order of preference:

  • a JsonNode,
  • an int,
  • any other object, or a collection of any object.

In the latter case, the appended information will be that object's .toString() result, or a JSON Array consisting of each of the underlying object's .toString() result. You can see where this is going: if you want to add your own object(s) into a validation report, it had better implement .toString() ;)

JSON representation of one message

An example tells more than a thousand words:

    {
        "domain": "validation",
        "keyword": "minimum",
        "message": "number is lower than the required minimum",
        "minimum": 0,
        "found": -1
    }

The three required fields, domain, keyword and message, are all there. The message is further adorned with information specific to that keyword/validation domain.

Current JSON Schema for one validation message

Well, this is JSON Schema after all, right? You should be able to validate that message. So, just in case:

    {
        "type": "object",
        "properties": {
            "domain": {
                "enum": [ "$ref resolving", "syntax", "validation", "unknown" ],
                "required": true
            },
            "keyword": {
                "type": "string",
                "required": true
            },
            "message": {
                "type": "string",
                "required": true
            }
        }
    }

A word of caution: yes, apart from the three defined properties, you can add as many keys to the object as you want, with as complex a (valid) JSON value you want. But think of your users, they probably will not thank you if you put a 3+ level deep object as a value ;)

Clone this wiki locally