Generic PropertyDescriptor puzzler
Consider the implementation of a validator, to do a range check.
Since I have a sneaky suspicion we gonna need to communicate with the user when the validation fails, lets prepare those messages in a resource-injectible bundle of bytes as follows. The problem with IT is all these darn users! They keep getting in the way of real progress, wanting silly features, finding silly bugs...
class ValidatorResource {
@ResourceAnnotation()
String property = "The property '%s'";
@ResourceAnnotation()
String isNull = "is null";
@ResourceAnnotation()
String lessThanMinimum = "is less than %s" ;
@ResourceAnnotation()
String equalsMinimum = "is equal to, not greater than %s";
@ResourceAnnotation()
String greaterThanMaximum = "is greater than %s";
@ResourceAnnotation()
String equalsMaximum = "is equal to, not less than %s";
public ValidatorResource() {
configurator.configure(this);
}
}
Now because we got so many types of numbers and dates and what-not, let's implement a generic range validator as follows, where our value type is Comparable.
abstract class ComparableRangeValidator<Value extends Comparable> {
public static final ValidatorResource resource = new ValidatorResource();
Value minimum;
Value maximum;
boolean nullable;
boolean exclusive;
public ComparableRangeValidator() {
}
private String format(NBeanProperty property, String format, Object ... args) {
return formatter.format(resource.property, property.getPropertyLabel()) +
formatter.format(format, args);
}
public String validate(NBeanProperty property, Value value) {
if (value == null) {
if (!nullable) {
return format(property, resource.isNull);
}
return null;
}
if (value.compareTo(minimum) < 0) {
return format(property, resource.lessThanMinimum, minimum);
}
if (value.compareTo(minimum) == 0 && exclusive) {
return format(property, resource.equalsMinimum, minimum);
}
if (value.compareTo(maximum) > 0) {
return format(property, resource.greaterThanMaximum, maximum);
}
if (value.compareTo(maximum) == 0 && exclusive) {
return format(property, resource.equalsMaximum, maximum);
}
return null;
}
public void setExclusive(boolean exclusive) {
this.exclusive = exclusive;
}
public boolean isExclusive() {
return exclusive;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
public boolean isNullable() {
return nullable;
}
public void setMinimum(Value minimum) {
this.minimum = minimum;
}
public Value getMinimum() {
return minimum;
}
public void setMaximum(Value maximum) {
this.maximum = maximum;
}
public Value getMaximum() {
return maximum;
}
}
Now we can very easily create validators for specific types, which are effectively type aliases, as follows.
class IntegerRangeValidator extends ComparableRangeValidator<Integer> {
}
Supoib!
Now let's check the PropertyDescriptor's of our minty IntegerRangeValidator.
public class IntegerRangeValidatorInsanityCheck {
public static void main(String[] args) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(IntegerRangeValidator.class);
for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
logger.info(property.getName(), property.getPropertyType());
}
}
}
INFO:logger:IntegerRangeValidator:main:123: (String) class :: (Class) Class INFO:logger:IntegerRangeValidator:main:123: (String) exclusive :: (Class) boolean INFO:logger:IntegerRangeValidator:main:123: (String) maximum :: (Class) Comparable INFO:logger:IntegerRangeValidator:main:123: (String) minimum :: (Class) Comparable INFO:logger:IntegerRangeValidator:main:123: (String) nullable :: (Class) boolean
Darn, the type of minimum and maximum is Comparable, as in the generic ComparableRangeValidator superclass. Houston, why can't it just be Integer like i want?! Cos i wanna coerce (integer) values in there from string resources, so i'm stumped!
- Login or register to post comments
- Printer-friendly version
- evanx's blog
- 503 reads





