Skip to content

Instantly share code, notes, and snippets.

@bmchild
Created September 14, 2012 20:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bmchild/3724363 to your computer and use it in GitHub Desktop.
Save bmchild/3724363 to your computer and use it in GitHub Desktop.
NotEquals Validator
// Some Examples on how it could be used
@NotEquals(rejectValues = 0, message = "Must not be 0")
private Integer number;
@NotEquals(rejectValues = {0, .5, 1}, message = "Must not be 0, .5, or 1")
private BigDecimal myDecimal;
/**
*
*/
package com.bmchild.validation.constraints;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
/**
* Checks the number does not equal any of the rejectedValues. <br />
* <br />
* Supported types are:
* BigDecimal,
* BigInteger,
* byte, short, int, long, double, float and their respective wrappers
* <br /><br />
* null elements are considered valid
* @author bchild
*
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { NotEqualsConstraintValidator.class })
public @interface NotEquals {
String message() default "cannot equal value";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
double[] rejectValues();
}
/**
*
*/
package com.bmchild.validation.constraints;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.commons.collections.CollectionUtils;
/**
* @author bchild
*
*/
public class NotEqualsConstraintValidator implements
ConstraintValidator<NotEquals, Number> {
private static final String DEC_PT = ".";
List<BigDecimal> rejectValues = null;
@Override
public void initialize(NotEquals constraintAnnotation) {
rejectValues = new ArrayList<BigDecimal>();
for (double number : constraintAnnotation.rejectValues()) {
rejectValues.add(new BigDecimal(number)
.setScale(findScale(String.valueOf(number)), BigDecimal.ROUND_HALF_UP));
}
}
/* (non-Javadoc)
* @see javax.validation.ConstraintValidator#isValid(java.lang.Object, javax.validation.ConstraintValidatorContext)
*/
@Override
public boolean isValid(Number value, ConstraintValidatorContext context) {
boolean isValid = false;
if(CollectionUtils.isNotEmpty(rejectValues) && value != null) {
boolean found = false;
for (BigDecimal rejectValue : rejectValues) {
String valueString = String.valueOf(value);
if (rejectValue.compareTo(new BigDecimal(valueString).setScale(
findScale(valueString), BigDecimal.ROUND_HALF_UP)) == 0) {
found = true;
break;
}
}
isValid = !found;
} else {
isValid = true;
}
return isValid;
}
private int findScale(String numString) {
int scale = 0;
if(numString.contains(DEC_PT)) {
scale = numString.substring( numString.indexOf(DEC_PT), numString.length()).length() -1 ;
}
return scale;
}
}
/**
*
*/
package com.bmchild.validation.constraints;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.test.util.ReflectionTestUtils;
import com.bmchild.test.validation.AbstractConstraintValidatorTest;
/**
* @author bchild
*
*/
public class NotEqualsConstraintValidatorTest extends AbstractConstraintValidatorTest {
private NotEqualsConstraintValidator validator = new NotEqualsConstraintValidator();
private double[] doubleValues = new double[]{2.5, 0, 1.3, 46};
@org.junit.Before
public void init() {
NotEquals ne = Mockito.mock(NotEquals.class);
when(ne.rejectValues()).thenReturn(doubleValues);
validator.initialize(ne);
}
/**
* Test method for {@link com.bmchild.validation.constraints.NotEqualsConstraintValidator#initialize(com.bmchild.validation.constraints.NotEquals)}.
*/
@SuppressWarnings("unchecked")
@Test
public void testInitialize() {
List<BigDecimal> rejectValues = (List<BigDecimal>) ReflectionTestUtils.getField(validator, "rejectValues");
assertEquals(doubleValues.length, rejectValues.size());
}
/**
* Test method for {@link com.bmchild.validation.constraints.NotEqualsConstraintValidator#isValid(java.lang.Number, javax.validation.ConstraintValidatorContext)}.
*/
@Test
public void testIsValid() {
assertTrue(validator.isValid(3, null));
assertFalse(validator.isValid(0, null));
assertTrue(validator.isValid(3.98, null));
assertFalse(validator.isValid(2.5, null));
assertTrue(validator.isValid(3.98f, null));
assertFalse(validator.isValid(1.30f, null));
assertTrue(validator.isValid(47L, null));
assertFalse(validator.isValid(46L, null));
assertTrue(validator.isValid(new Short("47"), null));
assertFalse(validator.isValid(new Short("46"), null));
assertTrue(validator.isValid(new Byte("47"), null));
assertFalse(validator.isValid(new Byte("46"), null));
assertTrue(validator.isValid(new BigDecimal("1.30000000001"), null));
assertFalse(validator.isValid(new BigDecimal("1.30000000000"), null));
assertTrue(validator.isValid(new BigInteger("47"), null));
assertFalse(validator.isValid(new BigInteger("46"), null));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment