Skip to content

Instantly share code, notes, and snippets.

@hferentschik
Last active August 29, 2015 14:04
Show Gist options
  • Save hferentschik/ea002c2d4f1427226a8b to your computer and use it in GitHub Desktop.
Save hferentschik/ea002c2d4f1427226a8b to your computer and use it in GitHub Desktop.
Type annotations and Hibernate Validator
public class Foo {
@Valid // !? needed or not? Atm this is needed to trigger iteration
private List<@Email String> myEmailList; // that's the case we should primarily address
// ...
}
public interface Tuple<V1, V2> {
V1 getValue1();
V2 getValue2();
// ...
}
public interface NonNullTuple<@NotNull V1, @NotNull V2> extends Tuple<V1, V2> {
// ...
}
public class StringTuple implements NonNullTuple<String, String> {
@Override
public String getValue1() { // so here we safe an @NotNull which we basically inherit
return null;
}
@Override
public String getValue2() {
return null;
}
// ...
}
public interface Producer<@NotNull V> {
V create();
}
public class StringProducer implements Producer<String> {
String create();
}
public interface Tuple<V1, V2> {
V1 getValue1();
V2 getValue2();
// ...
}
public class StringIntegerTuple implements Tuple<@NotNull String, @NotNull @Max(10) Number>> {
@Override
public String getValue1() {
return null;
}
@Override
public Number getValue2() {
return null;
}
}
// but would it not just be easier to do:
public class StringIntegerTuple implements Tuple<String, Number> {
@Override
@NotNull
public String getValue1() {
return null;
}
@Override
@Max(10)
public Number getValue2() {
return null;
}
}
public class TupleUser {
@Valid
private Tuple<@NotNull String, @NotNull, @Max(10) Number> myStringNumberTuple; // how will we map this to the actual values to be validated?
// ...
}
public class TupleWithTypeParameters<@NotNull V1, @NotNull, @Max(10) V2 extends Number> { // Hmm, why not apply constraints on the fields directly?
V1 value1;
V2 value2;
V1 getValue1() { // What do we do? Do we do field or getter validation? We probably would need another annotation to define this
return value1;
}
// ...
}
@gunnarmorling
Copy link

// how will we map this to the actual values to be validated?
My thinking is that we need to merge the meta-data given on the type declaration (i.e. the definition of the Tuple class) with the meta-data of this specific type use (here, Tuple<String, Number>).

So when retrieving the property meta-data during cascaded validation of myStringNumberTuple, we'd need to pass in a context, which basically has the following contents:

V1 = @NotNull,
V2 = @NotNull, @Max(10)

Then, when accessing the state of the object in myStringNumberTuple - e.g. when validating the property getValue1(), we'd detect it's of type V1 and apply the statically defined meta-data as well as the one passed in from the usage site (as you see we need to define how to access the state, i.e. via getter or field).

@hferentschik
Copy link
Author

Hmm, but would NonNullTuple potentially not violate the LSP?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment