Skip to content

Commit

Permalink
Provide default validation fallback messages
Browse files Browse the repository at this point in the history
In case of a missing messages.txt file, default messages are now
provided via the `ValidatorMessages` object.
  • Loading branch information
edgarmueller committed Sep 18, 2019
1 parent 82e1ca9 commit 0b41f8b
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 84 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/com/eclipsesource/schema/SchemaValidator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.eclipsesource.schema.internal._
import com.eclipsesource.schema.internal.refs.{DocumentCache, Ref, SchemaRefResolver, SchemaResolutionScope}
import com.eclipsesource.schema.internal.url.UrlStreamResolverFactory
import com.eclipsesource.schema.internal.validators.DefaultFormats
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json._
import scalaz.\/

Expand Down Expand Up @@ -105,7 +105,7 @@ class SchemaValidator(
private[schema] def readJson(json: JsValue)(implicit reads: Reads[SchemaType], lang: Lang): \/[JsonValidationError, SchemaType] = {
\/.fromEither(Json.fromJson[SchemaType](json).asEither)
.leftMap(errors =>
JsonValidationError(Messages("err.parse.json"), JsError.toJson(errors))
JsonValidationError(ValidatorMessages("err.parse.json"), JsError.toJson(errors))
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.eclipsesource.schema.internal

import java.text.MessageFormat

import com.osinka.i18n.{Lang, Messages}

import scala.util.Try

object ValidatorMessages {

val DefaultMessages: Map[String, String] = Map(
"obj.missing.prop.dep" -> "Missing property dependency {0}.",
"obj.max.props" -> "Too many properties. {0} properties found, but only a maximum of {1} is allowed.",
"obj.min.props" -> "Found {0} properties, but a minimum of {1} is required.",
"obj.additional.props" -> "Additional properties are not allowed, but found properties {0}.",
"obj.required.prop" -> "Property {0} missing.",
"arr.max" -> "Too many items. {0} items found, but only a maximum of {1} is allowed.",
"arr.min" -> "Found {0} items, but a minimum of {1} is required.",
"arr.dups" -> "Found duplicates.",
"arr.out.of.bounds" -> "Array index {0} out of bounds.",
"arr.invalid.index" -> "Invalid array index {0}.",
"str.pattern" -> "''{0}'' does not match pattern ''{1}''.",
"str.invalid.pattern" -> "Invalid pattern ''{0}''.",
"str.min.length" -> "''{0}'' does not match minimum length of {1}.",
"str.max.length" -> "''{0}'' exceeds maximum length of {1}.",
"str.format" -> "''{0}'' does not match format {1}.",
"num.multiple.of" -> "{0} is not a multiple of {1}.",
"num.max" -> "{0} exceeds maximum value of {1}.",
"num.max.exclusive" -> "{0} exceeds exclusive maximum value of {1}.",
"num.min" -> "{0} is smaller than required minimum value of {1}.",
"num.min.exclusive" -> "{0} is smaller than required exclusive minimum value of {1}.",
"any.not" -> "Instance matches schema although it must not.",
"any.all" -> "Instance does not match all schemas.",
"any.any" -> "Instance does not match any of the schemas.",
"any.one.of.none" -> "Instance does not match any schema.",
"any.one.of.many" -> "Instance matches more than one schema.",
"any.enum" -> "Instance is invalid enum value.",
"any.const" -> "Instance does not match const value.",
"comp.no.schema" -> "No schema applicable.",
"err.expected.type" -> "Wrong type. Expected {0}, was {1}.",
"err.unresolved.ref" -> "Could not resolve ref {0}.",
"err.prop.not.found" -> "Could not find property {0}.",
"err.ref.expected" -> "Expected to find ref at {0}.",
"err.res.scope.id.empty" -> "Resolution scope ID must not be empty.",
"err.parse.json" -> "Could not parse JSON.",
"err.max.depth" -> "Maximum recursion depth reached.",
"err.dependencies.not.found" -> "Dependency not found.",
"err.definitions.not.found" -> "Definition not found.",
"err.patternProperties.not.found" -> "Pattern Properties not found.",
"err.false.schema" -> "Boolean false schema encountered.",
"err.contains" -> "Array does not contain valid item.",
"err.if.then.else" -> "Conditional validation failed."
)

def apply(msg: String, args: Any*)(implicit lang: Lang): String = {
Try(Messages(msg, args:_*))
.getOrElse(
new MessageFormat(DefaultMessages(msg)).format(args.map(_.asInstanceOf[java.lang.Object]).toArray)
)
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.eclipsesource.schema.internal.draft4.constraints

import com.eclipsesource.schema.{SchemaInteger, SchemaNumber, SchemaResolutionContext, SchemaType, SchemaValue}
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil}
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil, ValidatorMessages}
import com.eclipsesource.schema.internal.constraints.Constraints._
import com.eclipsesource.schema.internal.validation.{Rule, VA}
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json.{JsNumber, JsString, JsValue}
import scalaz.Success

Expand Down Expand Up @@ -34,7 +34,7 @@ case class NumberConstraints4(min: Option[Minimum] = None,
case other =>
SchemaUtil.failure(
Keywords.Any.Type,
Messages("err.expected.type", "integer", SchemaUtil.typeOfAsString(other)),
ValidatorMessages("err.expected.type", "integer", SchemaUtil.typeOfAsString(other)),
context.schemaPath,
context.instancePath,
other
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.eclipsesource.schema.internal.draft7.constraints

import com.eclipsesource.schema.{SchemaInteger, SchemaNumber, SchemaResolutionContext, SchemaType, SchemaValue}
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil}
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil, ValidatorMessages}
import com.eclipsesource.schema.internal.constraints.Constraints._
import com.eclipsesource.schema.internal.validation.{Rule, VA}
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json.{JsNumber, JsString, JsValue}
import scalaz.Success

Expand Down Expand Up @@ -34,7 +34,7 @@ case class NumberConstraints7(min: Option[Minimum] = None,
case other =>
SchemaUtil.failure(
Keywords.Any.Type,
Messages("err.expected.type", "integer", SchemaUtil.typeOfAsString(other)),
ValidatorMessages("err.expected.type", "integer", SchemaUtil.typeOfAsString(other)),
context.schemaPath,
context.instancePath,
other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.eclipsesource.schema._
import com.eclipsesource.schema.internal._
import com.eclipsesource.schema.internal.constraints.Constraints.Constraint
import com.eclipsesource.schema.internal.url.UrlStreamResolverFactory
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json._
import scalaz.syntax.either._
import scalaz.{\/, \/-}
Expand Down Expand Up @@ -65,7 +65,7 @@ case class SchemaRefResolver
val updatedScope = updateResolutionScope(scope.copy(depth = scope.depth + 1), current)

if (scope.depth >= MaxDepth) {
JsonValidationError(Messages("err.max.depth")).left
JsonValidationError(ValidatorMessages("err.max.depth")).left
} else {
val result: \/[JsonValidationError, ResolvedResult] = ref match {

Expand Down Expand Up @@ -112,7 +112,7 @@ case class SchemaRefResolver
}
}
private[schema] def resolutionFailure(ref: Ref)(implicit lang: Lang): JsonValidationError =
JsonValidationError(Messages("err.unresolved.ref", ref.value))
JsonValidationError(ValidatorMessages("err.unresolved.ref", ref.value))

private def resolveRelative(ref: RelativeRef, scope: SchemaResolutionScope, instance: SchemaType)
(implicit lang: Lang): \/[JsonValidationError, ResolvedResult] = {
Expand Down Expand Up @@ -201,7 +201,7 @@ case class SchemaRefResolver
source <- if (url.getProtocol == null || version.options.supportsExternalReferences) {
\/.fromEither(Try { Source.fromURL(url) }.toJsonEither)
} else {
JsonValidationError(Messages("err.unresolved.ref")).left
JsonValidationError(ValidatorMessages("err.unresolved.ref")).left
}
read <- readSource(source)
} yield {
Expand All @@ -217,7 +217,7 @@ case class SchemaRefResolver

private[schema] def readJson(json: JsValue)(implicit lang: Lang): \/[JsonValidationError, SchemaType] = \/.fromEither(Json.fromJson[SchemaType](json).asEither)
.leftMap(errors =>
JsonValidationError(Messages("err.parse.json"), JsError.toJson(errors))
JsonValidationError(ValidatorMessages("err.parse.json"), JsError.toJson(errors))
)

private[schema] def readSource(source: Source)(implicit lang: Lang): \/[JsonValidationError, SchemaType] = {
Expand Down Expand Up @@ -286,22 +286,22 @@ case class SchemaRefResolver
private def resolveConstraint[A <: Constraint](constraints: A, constraint: String)
(implicit lang: Lang): Either[JsonValidationError, SchemaType] = {
constraints.resolvePath(constraint).fold[Either[JsonValidationError, SchemaType]](
Left(JsonValidationError(Messages("err.unresolved.ref", constraint)))
Left(JsonValidationError(ValidatorMessages("err.unresolved.ref", constraint)))
)(schema => Right(schema))
}

private def findProp(props: Seq[SchemaProp], propName: String)
(implicit lang: Lang): Either[JsonValidationError, SchemaType] = {
props.collectFirst {
case SchemaProp(name, s) if name == propName => s
}.toRight(JsonValidationError(Messages("err.prop.not.found", propName)))
}.toRight(JsonValidationError(ValidatorMessages("err.prop.not.found", propName)))
}

private def findOtherProp(props: Seq[(String, SchemaType)], propName: String)
(implicit lang: Lang): Either[JsonValidationError, SchemaType] = {
props.collectFirst {
case (name, s) if name == propName => s
}.toRight(JsonValidationError(Messages("err.prop.not.found", propName)))
}.toRight(JsonValidationError(ValidatorMessages("err.prop.not.found", propName)))
}


Expand All @@ -317,7 +317,7 @@ case class SchemaRefResolver
schema match {

case SchemaMap(name, members) =>
members.find(_.name == fragmentPart).map(_.schemaType).toRight(JsonValidationError(Messages(s"err.$name.not.found")))
members.find(_.name == fragmentPart).map(_.schemaType).toRight(JsonValidationError(ValidatorMessages(s"err.$name.not.found")))

case SchemaSeq(members) =>
fragmentPart match {
Expand Down Expand Up @@ -355,9 +355,9 @@ case class SchemaRefResolver
if (idx > 0 && idx < arr.value.size) {
Right(SchemaValue(arr.value(idx)))
} else {
Left(JsonValidationError(Messages("arr.out.of.bounds", index)))
Left(JsonValidationError(ValidatorMessages("arr.out.of.bounds", index)))
}
case _ => Left(JsonValidationError(Messages("arr.invalid.index", fragmentPart)))
case _ => Left(JsonValidationError(ValidatorMessages("arr.invalid.index", fragmentPart)))
}

case CompoundSchemaType(alternatives) =>
Expand All @@ -366,7 +366,7 @@ case class SchemaRefResolver
)
results
.collectFirst { case r@Right(_) => r }
.getOrElse(Left(JsonValidationError(Messages("err.unresolved.ref", fragmentPart))))
.getOrElse(Left(JsonValidationError(ValidatorMessages("err.unresolved.ref", fragmentPart))))

case n: SchemaNumber => resolveConstraint(n.constraints, fragmentPart)
case n: SchemaInteger => resolveConstraint(n.constraints, fragmentPart)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package com.eclipsesource.schema.internal.validators
import com.eclipsesource.schema.internal._
import com.eclipsesource.schema.internal.validation.{Rule, VA}
import com.eclipsesource.schema.{SchemaObject, SchemaResolutionContext, SchemaType}
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json._
import scalaz.{Failure, Success}

import scala.annotation.tailrec
import scalaz.{Failure, Success}

object AnyConstraintValidators {

Expand All @@ -25,7 +25,7 @@ object AnyConstraintValidators {
} else {
SchemaUtil.failure(
"else",
Messages("err.if.then.else", json),
ValidatorMessages("err.if.then.else", json),
context.schemaPath,
context.instancePath,
json
Expand All @@ -40,7 +40,7 @@ object AnyConstraintValidators {
} else {
SchemaUtil.failure(
"then",
Messages("err.if.then.else", json),
ValidatorMessages("err.if.then.else", json),
context.schemaPath,
context.instancePath,
json
Expand All @@ -54,7 +54,7 @@ object AnyConstraintValidators {
} else {
SchemaUtil.failure(
"else",
Messages("err.if.then.else", json),
ValidatorMessages("err.if.then.else", json),
context.schemaPath,
context.instancePath,
json
Expand All @@ -75,7 +75,7 @@ object AnyConstraintValidators {
} else {
SchemaUtil.failure(
Keywords.Any.Not,
Messages("any.not", json),
ValidatorMessages("any.not", json),
context.schemaPath,
context.instancePath,
json
Expand All @@ -99,7 +99,7 @@ object AnyConstraintValidators {
} else {
SchemaUtil.failure(
Keywords.Any.AllOf,
Messages("any.all"),
ValidatorMessages("any.all"),
context.schemaPath,
context.instancePath,
json,
Expand Down Expand Up @@ -134,7 +134,7 @@ object AnyConstraintValidators {
case Nil => Success(json)
case errors => SchemaUtil.failure(
Keywords.Any.AnyOf,
Messages("any.any"),
ValidatorMessages("any.any"),
context.schemaPath,
context.instancePath,
json,
Expand All @@ -159,7 +159,7 @@ object AnyConstraintValidators {
case 0 =>
SchemaUtil.failure(
Keywords.Any.OneOf,
Messages("any.one.of.none"),
ValidatorMessages("any.one.of.none"),
context.schemaPath,
context.instancePath,
json,
Expand All @@ -174,7 +174,7 @@ object AnyConstraintValidators {
}
SchemaUtil.failure(
Keywords.Any.OneOf,
Messages("any.one.of.many"),
ValidatorMessages("any.one.of.many"),
context.schemaPath,
context.instancePath,
json,
Expand All @@ -195,7 +195,7 @@ object AnyConstraintValidators {
case None => Success(json)
case Some(constValue) => SchemaUtil.failure(
"const",
Messages("any.const"),
ValidatorMessages("any.const"),
context.schemaPath,
context.instancePath,
json,
Expand All @@ -215,7 +215,7 @@ object AnyConstraintValidators {
case Some(values) =>
SchemaUtil.failure(
Keywords.Any.Enum,
Messages("any.enum"),
ValidatorMessages("any.enum"),
context.schemaPath,
context.instancePath,
json,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.eclipsesource.schema.internal.validators

import com.eclipsesource.schema.internal.validation.Rule
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil}
import com.eclipsesource.schema.internal.{Keywords, SchemaUtil, ValidatorMessages}
import com.eclipsesource.schema.{SchemaResolutionContext, SchemaType}
import com.osinka.i18n.{Lang, Messages}
import com.osinka.i18n.Lang
import play.api.libs.json.{JsArray, JsValue}

import scalaz.Success

object ArrayConstraintValidators {
Expand All @@ -20,7 +19,7 @@ object ArrayConstraintValidators {
.map(Success(_))
.getOrElse(SchemaUtil.failure(
"contains",
Messages("err.contains"),
ValidatorMessages("err.contains"),
context.schemaPath.map(_ \ "contains"),
context.instancePath,
json
Expand All @@ -42,7 +41,7 @@ object ArrayConstraintValidators {
} else {
SchemaUtil.failure(
Keywords.Array.MaxItems,
Messages("arr.max", values.size, max),
ValidatorMessages("arr.max", values.size, max),
context.schemaPath,
context.instancePath,
json
Expand All @@ -64,7 +63,7 @@ object ArrayConstraintValidators {
} else {
SchemaUtil.failure(
Keywords.Array.MinItems,
Messages("arr.min", values.size, minItems),
ValidatorMessages("arr.min", values.size, minItems),
context.schemaPath,
context.instancePath,
json
Expand All @@ -84,7 +83,7 @@ object ArrayConstraintValidators {
} else {
SchemaUtil.failure(
Keywords.Array.UniqueItems,
Messages("arr.dups"),
ValidatorMessages("arr.dups"),
context.schemaPath,
context.instancePath,
json
Expand All @@ -99,7 +98,7 @@ object ArrayConstraintValidators {
(implicit lang: Lang) =
SchemaUtil.failure(
Keywords.Any.Type,
Messages("err.expected.type", "array", SchemaUtil.typeOfAsString(json)),
ValidatorMessages("err.expected.type", "array", SchemaUtil.typeOfAsString(json)),
context.schemaPath,
context.instancePath,
json
Expand Down

0 comments on commit 0b41f8b

Please sign in to comment.