Last active
October 21, 2017 00:08
-
-
Save gabfssilva/4795245c49272ede703afaf32b340e1c to your computer and use it in GitHub Desktop.
java 8 based validator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.validation.java; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Set; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
/** | |
* @author Gabriel Francisco <[email protected]> | |
*/ | |
public interface Result { | |
default boolean isFailure() { | |
return this instanceof Failure; | |
} | |
static <T> Stream<Validation> validations(Validator<T> validator, T bean) { | |
return validator.validator | |
.stream() | |
.flatMap(f -> f.apply(bean)); | |
} | |
static <R extends Result, T> R of(Validator<T> validator, T bean) { | |
final Set<Violation> violations = validations(validator, bean) | |
.filter(v -> !v.getRequirement()) | |
.map(Validation::<Failure>result) | |
.map(Failure::getViolations) | |
.flatMap(Collection::stream) | |
.collect(Collectors.toSet()); | |
if (violations.isEmpty()) return (R) new Success(); | |
return (R) new Failure(violations); | |
} | |
} | |
class Success implements Result { | |
@Override | |
public String toString() { | |
return "Success{}"; | |
} | |
} | |
class Failure implements Result { | |
private Set<Violation> violations; | |
public Failure(Violation violation) { | |
this.violations = Collections.singleton(violation); | |
} | |
public Failure(Set<Violation> violations) { | |
this.violations = violations; | |
} | |
public Set<Violation> getViolations() { | |
return violations; | |
} | |
@Override | |
public String toString() { | |
return "Failure{" + | |
"violations=" + violations + | |
'}'; | |
} | |
} | |
-------------------------- | |
package org.validation.java; | |
import java.util.function.Supplier; | |
import java.util.stream.Stream; | |
public class Validation { | |
private String field; | |
private Boolean requirement; | |
private Supplier<String> message; | |
public static Stream<Validation> require(Boolean requirement, String message) { | |
return Stream.of(new Validation(requirement, message)); | |
} | |
public Validation(String field, Boolean requirement, Supplier<String> message) { | |
this.field = field; | |
this.requirement = requirement; | |
this.message = message; | |
} | |
public Validation(String field, Boolean requirement, String message) { | |
this.field = field; | |
this.requirement = requirement; | |
this.message = () -> message; | |
} | |
public Validation(Boolean requirement, String message) { | |
this.requirement = requirement; | |
this.message = () -> message; | |
} | |
public Validation(Boolean requirement, Supplier<String> message) { | |
this.requirement = requirement; | |
this.message = message; | |
} | |
public Boolean getRequirement() { | |
return requirement; | |
} | |
public Supplier<String> getMessage() { | |
return message; | |
} | |
public String getField() { | |
return field; | |
} | |
public <T extends Result> T result() { | |
if (requirement) return (T) new Success(); | |
return (T) new Failure(new Violation(field, message.get())); | |
} | |
} | |
------------------------------------- | |
package org.validation.java; | |
import java.util.HashSet; | |
import java.util.Set; | |
import java.util.function.Function; | |
import java.util.stream.Stream; | |
import static org.validation.java.Validation.require; | |
/** | |
* @author Gabriel Francisco <[email protected]> | |
*/ | |
public class Validator<T> { | |
protected Set<Function<T, Stream<Validation>>> validator; | |
private Validator(Set<Function<T, Stream<Validation>>> validator) { | |
this.validator = validator; | |
} | |
public static <T> ValidatorBuilder<T> newValidator() { | |
return new ValidatorBuilder<>(); | |
} | |
public Stream<Validation> validations(T bean) { | |
return Result.validations(this, bean); | |
} | |
public Result validate(T bean) { | |
return Result.of(this, bean); | |
} | |
public static class ValidatorBuilder<T> { | |
protected Set<Function<T, Stream<Validation>>> validators = new HashSet<>(); | |
public ValidatorBuilder<T> withValidation(Function<T, Stream<Validation>> func) { | |
validators.add(func); | |
return this; | |
} | |
public Validator<T> build() { | |
return new Validator<>(validators); | |
} | |
} | |
} |
Kotlin:
data class User(val id: Long, val name: String)
val userValidator =
Validator
.newValidator<User>()
.withValidation { require(it.name.isNotEmpty(), "name cannot be empty") }
.withValidation { require(it.id > 0, "id cannot be lower than 1")}
object Exec {
@JvmStatic
fun main(args: Array<String>) {
println(userValidator.validate(User(1L, "")))
}
}
Scala:
case class AddressScala(address: String)
case class UserScala(id: Long, name: String, address: AddressScala)
object SampleScala extends App {
val addressValidator =
Validator.newValidator[AddressScala]()
.withValidation { a => require(a.address != null, "address cannot be empty") }
.build()
val userValidator =
Validator.newValidator[UserScala]()
.withValidation { u => require(u.name.nonEmpty, "name cannot be empty") }
.withValidation { u => require(u.id > 0, "id cannot be lower than 1") }
.withValidation { u => addressValidator.validations(u.address) }
.build()
println(
userValidator.validate(UserScala(1l, "", AddressScala(null)))
)
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Java: