/* * Copyright 2011 Eric F. Savage, code@efsavage.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ajah.spring.mvc.form.validation; import java.lang.reflect.Field; import java.util.logging.Level; import lombok.extern.java.Log; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import com.ajah.crypto.Password; import com.ajah.spring.mvc.form.AutoFormUtils; import com.ajah.util.ToStringable; /** * Validates {@link StringSize} annotations. * * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a * href="mailto:code@efsavage.com">code@efsavage.com</a>. * */ @Log public class StringSizeValidator implements Validator { private static Object[] getArgs(final Field field, final StringSize stringSize) { return new Object[] { AutoFormUtils.getLabel(field), Integer.valueOf(stringSize.min()), Integer.valueOf(stringSize.max()) }; } /** * This validator realistically only supports properties with the * {@link ToStringable} attribute, but there's no real reason to enforce * this restriction. * * @return Always returns true */ @Override public boolean supports(final Class<?> clazz) { return true; } /** * Look for {@link StringSize} annotated fields, and checks the min/max * values against the {@link Object#toString()} methods. * * @see org.springframework.validation.Validator#validate(java.lang.Object, * org.springframework.validation.Errors) */ @Override public void validate(final Object target, final Errors errors) { log.finest("Validating " + target.getClass().getName()); for (final Field field : target.getClass().getFields()) { if (field.isAnnotationPresent(StringSize.class)) { final String fieldName = field.getName(); log.fine("Validating " + StringSize.class.getSimpleName() + " on " + fieldName); final StringSize stringSize = field.getAnnotation(StringSize.class); Object value; try { value = field.get(target); } catch (final IllegalAccessException e) { log.log(Level.SEVERE, e.getMessage(), e); errors.rejectValue(fieldName, StringSize.class.getSimpleName(), getArgs(field, stringSize), stringSize.message()); return; } final String stringValue = value != null ? value.toString() : ""; int len = stringValue.length(); if (value instanceof Password) { len = ((Password) value).getOriginalLength(); } log.fine("Value is " + len + " chars [min=" + stringSize.min() + ", max=" + stringSize.max() + "]"); if (len < stringSize.min()) { errors.rejectValue(fieldName, StringSize.class.getSimpleName(), getArgs(field, stringSize), stringSize.message()); } if (len > stringSize.min()) { errors.rejectValue(fieldName, StringSize.class.getSimpleName(), getArgs(field, stringSize), stringSize.message()); } } } } }