How to validate if a field is set?
atkawa7 opened this issue · 2 comments
atkawa7 commented
Hi @making. Got a question
I have class that has two fields. How do I validate whether one field is set. The two fields cannot be set at the same time and both cannot be null as well. How do I validate this so that when both are set I get an error These two fields cannot be set concurrently
and These two fields cannot be null
when both are null
public static class Document {
private String fileId;
private String url;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Here is what I have and it helps but its not outputting the correct message
import am.ik.yavi.builder.ValidatorBuilder;
import am.ik.yavi.constraint.CharSequenceConstraint;
import am.ik.yavi.core.Constraint;
import am.ik.yavi.core.ConstraintViolation;
import java.util.Objects;
import static java.util.Objects.isNull;
public class SampleMain {
public static class Document {
private String fileId;
private String url;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
public static void main(String[] args) {
var result = ValidatorBuilder.of(Document.class)
.constraintOnCondition((document, constraintContext) ->
isNull(document.getFileId()), b -> b.constraint(Document::getUrl, "url", c->c.notBlank().url()))
.constraintOnCondition((document, constraintContext) ->
Objects.nonNull(document.getFileId()), b -> b.constraint(Document::getUrl, "url", Constraint::isNull))
.constraintOnCondition((document, constraintContext) -> isNull(document.getUrl()),
b -> b.constraint(Document::getFileId, "fileId", CharSequenceConstraint::notBlank))
.constraintOnCondition((document, constraintContext) -> Objects.nonNull(document.getUrl()), b -> b.constraint(Document::getFileId, "fileId", CharSequenceConstraint::isNull))
.build();
var document = new Document();
document.setUrl("https://example.com");
document.setFileId("xxxxxxxxxxxxxxxxx");
var errors = result.validate(document);
for (ConstraintViolation error : errors) {
System.out.println(error.detail());
}
}
}
ViolationDetail{key='object.isNull', args=[url, https://example.com], defaultMessage='"url" must be null'}
ViolationDetail{key='object.isNull', args=[fileId, xxxxxxxxxxxxxxxxx], defaultMessage='"fileId" must be null'}
making commented
It sounds like a usecase for cross-field validation
https://yavi.ik.am/#cross-field-validation
atkawa7 commented
@making Thanks this is perfect for my case. Closing this
public static void main(String[] args) {
var result =
of(Document.class)
.constraintOnTarget(document -> isNull(document.getUrl()) || isNull(document.getFileId()),
"url", "url.bothNonNull", "Both \"url\" and \"fileId\" must not be set")
.constraintOnTarget(document -> nonNull(document.getUrl()) || nonNull(document.getFileId()),
"url", "url.bothNotNull", "Both \"url\" and \"fileId\" must not be null")
.build();
var document = new Document();
document.setUrl("https://example.com");
document.setFileId("xxxxxxxxxxxxxxxxx");
var errors = result.validate(document);
for (ConstraintViolation error : errors) {
System.out.println(error.message());
}
}
Result ->
Both "url" and "fileId" must not be set