Validate mapper

Powerful validate mapper https://github.com/zTrap/validate-mapper

License

License

the apache software license, version 2.0
GroupId

GroupId

ru.ztrap.tools
ArtifactId

ArtifactId

validate-mapper
Last Version

Last Version

1.0.9
Release Date

Release Date

Type

Type

jar
Description

Description

Validate mapper
Powerful validate mapper https://github.com/zTrap/validate-mapper
Project URL

Project URL

https://github.com/zTrap/validate-mapper
Source Code Management

Source Code Management

https://github.com/zTrap/validate-mapper

Download validate-mapper

How to add to project

<!-- https://jarcasting.com/artifacts/ru.ztrap.tools/validate-mapper/ -->
<dependency>
    <groupId>ru.ztrap.tools</groupId>
    <artifactId>validate-mapper</artifactId>
    <version>1.0.9</version>
</dependency>
// https://jarcasting.com/artifacts/ru.ztrap.tools/validate-mapper/
implementation 'ru.ztrap.tools:validate-mapper:1.0.9'
// https://jarcasting.com/artifacts/ru.ztrap.tools/validate-mapper/
implementation ("ru.ztrap.tools:validate-mapper:1.0.9")
'ru.ztrap.tools:validate-mapper:jar:1.0.9'
<dependency org="ru.ztrap.tools" name="validate-mapper" rev="1.0.9">
  <artifact name="validate-mapper" type="jar" />
</dependency>
@Grapes(
@Grab(group='ru.ztrap.tools', module='validate-mapper', version='1.0.9')
)
libraryDependencies += "ru.ztrap.tools" % "validate-mapper" % "1.0.9"
[ru.ztrap.tools/validate-mapper "1.0.9"]

Dependencies

compile (1)

Group / Artifact Type Version
org.jetbrains.kotlin : kotlin-stdlib-jdk8 jar 1.4.31

Project Modules

There are no modules declared in this project.

Validation mapper

Powerful reflection-based data validator. Mostly used for mapping and validating network-layer models

Install

Base library Download

implementation "ru.ztrap.tools:validate-mapper:${latestVersion}"

Common checks Download

implementation "ru.ztrap.tools:validate-mapper-common:${latestVersion}"

Gson extension Download

implementation "ru.ztrap.tools:validate-mapper-gson:${latestVersion}"

Usage

1. Basics

Let's imagine we have a simple Message model which contains id, senderId, text and attachmentUrl. Fields id and senderId should not be empty or blank, text and attachmentUrl are not required and can be null. In code, it will be represented like this:

data class MessageNetworkEntity(
    @Checks(NotBlankStringCheck::class)
    val id: String?,
    @Checks(NotBlankStringCheck::class)
    val senderId: String?,
    @Checks(NotBlankStringCheck::class)
    val text: String?,
    @NotRequired
    val attachmentUrl: String?
) {
    companion object : ValidateMapper<MessageNetworkEntity, MessageDomainEntity>() {
        override fun transform(raw: MessageNetworkEntity) = MessageDomainEntity(
            id = requireNotNull(raw.id),
            text = raw.text,
            senderId = requireNotNull(raw.senderId),
            attachmentUrl = raw.attachmentUrl
        )
    }
}

data class MessageDomainEntity(
    val id: String,
    val text: String,
    val senderId: String,
    val attachmentUrl: String?
)

We can validate this network model with:

val networkMessage = MessageNetworkEntity(
    id = "7c0518f7-874d-4dd7-89b6-af0adf0699a1",
    senderId = "347da584-9f8c-4b47-b912-f9f2af0a6417",
    text = "Hello!",
    attachmentUrl = "https://avatars.githubusercontent.com/u/18091396?s=460&u=72fb5fb2f4d8a2ef3b6195ee371a130532656095&v=4"
)

val domainMessage = networkMessage.validateMap(MessageNetworkEntity)

If some constraint is not met, validateMap will throw a FailedValidationException and provide detailed explanation of what is not met. Example:

val networkMessage = MessageNetworkEntity(
    id = "",
    senderId = " ",
    text = null,
    attachmentUrl = "https://avatars.githubusercontent.com/u/18091396?s=460&u=72fb5fb2f4d8a2ef3b6195ee371a130532656095&v=4"
)

val domainMessage = networkMessage.validateMap(MessageNetworkEntity)

Will throw exception with following message:

ru.ztrap.tools.validate.mapper.FailedValidationException: Failed validation of received object.
    Object -> MessageNetworkEntity(id=, senderId= , text=null, attachmentUrl=https://avatars.githubusercontent.com/u/18091396?s=460&u=72fb5fb2f4d8a2ef3b6195ee371a130532656095&v=4)
    Params -> id ------- Reasons -> [{reason="empty string"}],
              senderId - Reasons -> [{reason="blank string"}],
              text ----- Reasons -> [{reason="value is null"}]
    ...

2. Parametrized checks

You can provide named parameters into any ValidateChecker via any of this annotations

annotation class StringParameter(val name: String, val value: String)
annotation class ByteParameter(val name: String, val value: Byte)
annotation class ShortParameter(val name: String, val value: Short)
annotation class IntParameter(val name: String, val value: Int)
annotation class LongParameter(val name: String, val value: Long)
annotation class FloatParameter(val name: String, val value: Float)
annotation class DoubleParameter(val name: String, val value: Double)
annotation class KClassParameter(val name: String, val value: KClass<*>)

Let's add length checks to unique id fields:

private const val MAX_UUID_LENGTH = 36L

data class MessageNetworkEntity(
    @CheckParametrized(
        expressionClass = TrimmedStringLengthCheck::class,
        long = [
            CheckParametrized.LongParameter(TrimmedStringLengthCheck.MAX_LIMIT_LONG, MAX_UUID_LENGTH),
            CheckParametrized.LongParameter(TrimmedStringLengthCheck.MIN_LIMIT_LONG, MAX_UUID_LENGTH)
        ]
    )
    val id: String?,
    @CheckParametrized(
        expressionClass = TrimmedStringLengthCheck::class,
        long = [
            CheckParametrized.LongParameter(TrimmedStringLengthCheck.MAX_LIMIT_LONG, MAX_UUID_LENGTH),
            CheckParametrized.LongParameter(TrimmedStringLengthCheck.MIN_LIMIT_LONG, MAX_UUID_LENGTH)
        ]
    )
    val senderId: String?,
    ...
)

And validate:

val networkMessage = MessageNetworkEntity(
    id = "52b1c9c5-3cb2-41f0", // invalid
    senderId = "52b1c9c5-3cb2-41f0-adff-1b0da5cffeee",
    text = null,
    attachmentUrl = "https://avatars.githubusercontent.com/u/18091396?s=460&u=72fb5fb2f4d8a2ef3b6195ee371a130532656095&v=4"
)

val domainMessage = networkMessage.validateMap(MessageNetworkEntity)

As result, we get thrown exception with following message:

ru.ztrap.tools.validate.mapper.FailedValidationException: Failed validation of received object.
    Object -> MessageNetworkEntity(id=52b1c9c5-3cb2-41f0, senderId=52b1c9c5-3cb2-41f0-adff-1b0da5cffeee, text=null, attachmentUrl=https://avatars.githubusercontent.com/u/18091396?s=460&u=72fb5fb2f4d8a2ef3b6195ee371a130532656095&v=4)
    Params -> id - Reasons -> [{reason="length not in limits", values=[min_limit=36, max_limit=36, current_length=18]}]
    ...

3. Global configuration

You can define checks for all fields with provided type. For example, we expect all strings can't be blank.

ValidateMapper.addGlobalCheck(String::class, NotBlankStringCheck::class)

In some cases you may want to exclude checks from global pool for some field. You can simply do this with:

data class MessageNetworkEntity(
    @ExcludeCkecks(NotBlankStringCheck::class)
    val text: String?,
    ...
)

Also, you can provide field name extractor. Actual for models parsed from json. Example you can find here

Developed By

License

   Copyright 2021 zTrap

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

Versions

Version
1.0.9
1.0.8