Package org.internna.iwebmvc.core.validation

Source Code of org.internna.iwebmvc.core.validation.ValidationVisitor

/*
* Copyright 2002-2007 the original author or authors.
*
* 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 org.internna.iwebmvc.core.validation;

import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.internna.iwebmvc.core.validation.annotation.BeanConstraint;
import org.internna.iwebmvc.core.validation.annotation.CollectionConstraint;
import org.internna.iwebmvc.core.validation.annotation.DateConstraint;
import org.internna.iwebmvc.core.validation.annotation.NumberConstraint;
import org.internna.iwebmvc.core.validation.annotation.StringConstraint;
import org.internna.iwebmvc.core.visitor.FieldVisitor;
import org.internna.iwebmvc.core.visitor.Visitable;
import org.internna.iwebmvc.utils.Assert;
import org.springframework.stereotype.Component;

/**
* Visitor implementation that validates an object.
*
* @author Jose Noheda
* @since 1.0
*/
@Component
public class ValidationVisitor implements FieldVisitor {

    protected static final String[] errorCodes = {"error.required", "error.regexp", "error.min", "error.max"};

    /**
     * Visits a {@link org.internna.iwebmvc.core.visitor.Visitable} object.
     * @param element a Visitable object
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T visit(final Object element) {
        Assert.isInstanceOf(Visitable.class, element);
        return (T) visit((Visitable) element);
    }

    /**
     * Visits a Vistable object calling its accept method.
     *
     * @param entity any Visitable
     * @return a clone
     */
    protected final Collection<ValidationError> visit(final Visitable entity) {
        return entity.accept(this);
    }

    /**
     * Validates any field.
     *
     * @param field the field being validated
     * @param fieldValue the value of that field
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> Collection<T> visit(final Field field, final Object fieldValue) {
        Assert.notNull(field);
        Collection<ValidationError> errors = new HashSet<ValidationError>();
        errors.addAll(validateStringConstraint(field, fieldValue));
        errors.addAll(validateNumericConstraint(field, fieldValue));
        errors.addAll(validateDateConstraint(field, fieldValue));
        errors.addAll(validateBeanConstraint(field, fieldValue));
        errors.addAll(validateCollectionConstraint(field, fieldValue));
        return (Collection<T>) errors;
    }

    /**
     * Validates a
     * {@link org.internna.iwebmvc.core.validation.annotation.StringConstraint}.
     *
     * @param field the field to be validated
     * @param object the value to be validated
     * @return a collection of {@link ValidationError}
     */
    protected Set<ValidationError> validateStringConstraint(final Field field, final Object object) {
        final StringConstraint stringConstraint = field.getAnnotation(StringConstraint.class);
        Set<ValidationError> errors = new HashSet<ValidationError>();
        if (stringConstraint != null) {
            if (stringConstraint.required() & (object == null)) errors.add(new ValidationError(field.getName(), errorCodes[0], stringConstraint, object));
            if ((object != null) & (stringConstraint.regexp().length() > 0)) {
                try {
                    Pattern pattern = Pattern.compile(stringConstraint.regexp());
                    Matcher matcher = pattern.matcher(object.toString());
                    if (!matcher.matches()) errors.add(new ValidationError(field.getName(), errorCodes[1], stringConstraint, object));
                } catch (Exception ex) {
                    throw new ValidationException(ex);
                }
            }
            if ((object != null) & (stringConstraint.minLength() > 0)) {
                if (object.toString().length() < stringConstraint.minLength()) errors.add(new ValidationError(field.getName(), errorCodes[2], stringConstraint, object));
            }
            if ((object != null) & (stringConstraint.maxLength() > 0)) {
                if (object.toString().length() > stringConstraint.maxLength()) errors.add(new ValidationError(field.getName(), errorCodes[3], stringConstraint, object));
            }
        }
        return errors;
    }

    protected Set<ValidationError> validateNumericConstraint(final Field field, final Object object) {
        final NumberConstraint numberConstraint = field.getAnnotation(NumberConstraint.class);
        Set<ValidationError> errors = new HashSet<ValidationError>();
        if (numberConstraint != null) {
            if (numberConstraint.required() & (object == null)) errors.add(new ValidationError(field.getName(), errorCodes[0], numberConstraint, object));
            if (object != null) {
                double numericValue = ((Number) object).doubleValue();
                if (numberConstraint.minValue() > numericValue) errors.add(new ValidationError(field.getName(), errorCodes[2], numberConstraint, object));
                if (numberConstraint.maxValue() < numericValue) errors.add(new ValidationError(field.getName(), errorCodes[3], numberConstraint, object));
            }
        }
        return errors;
    }

    /**
     * Validates a
     * {@link org.internna.iwebmvc.core.validation.annotation.DateConstraint}.
     *
     * @param field the field to be validated
     * @param object the value to be validated
     * @return a collection of {@link ValidationError}
     */
    protected Set<ValidationError> validateDateConstraint(final Field field, final Object object) {
        final DateConstraint dateConstraint = field.getAnnotation(DateConstraint.class);
        Set<ValidationError> errors = new HashSet<ValidationError>();
        if (dateConstraint != null) {
            if (dateConstraint.required() & (object == null)) errors.add(new ValidationError(field.getName(), errorCodes[0], dateConstraint, object));
            if (object != null) {
                Calendar min = dateConstraint.minValue().getDate(false);
                Calendar max = dateConstraint.maxValue().getDate(true);
                Calendar date = Calendar.getInstance();
                date.setTime((Date) object);
                if (date.before(min)) errors.add(new ValidationError(field.getName(), errorCodes[2], dateConstraint, object));
                if (date.after(max)) errors.add(new ValidationError(field.getName(), errorCodes[3], dateConstraint, object));
            }
        }
        return errors;
    }

    protected Set<ValidationError> validateBeanConstraint(final Field field, final Object bean) {
        Set<ValidationError> errors = new HashSet<ValidationError>();
        BeanConstraint beanConstraint = field.getAnnotation(BeanConstraint.class);
        if (beanConstraint != null) {
            if (beanConstraint.required() & (bean == null)) errors.add(new ValidationError(field.getName(), errorCodes[0], beanConstraint, bean));
            if ((bean != null) && (beanConstraint.traverse())) {
                Collection<ValidationError> deepErrors = this.visit(bean);
                for (ValidationError error : deepErrors) error.addPath(field.getName());
                errors.addAll(deepErrors);
            }
        }
        return errors;
    }

    @SuppressWarnings("unchecked")
    protected Set<ValidationError> validateCollectionConstraint(final Field field, final Object collection) {
        Set<ValidationError> errors = new HashSet<ValidationError>();
        CollectionConstraint collectionConstraint = field.getAnnotation(CollectionConstraint.class);
        if (collectionConstraint != null) {
            if (collectionConstraint.required() & (collection == null)) errors.add(new ValidationError(field.getName(), errorCodes[0], collectionConstraint, collection));
            if (collection != null) {
                if (Collection.class.isInstance(collection)) {
                    Collection<?> col = (Collection<?>) collection;
                    if (collectionConstraint.traverse()) {
                        Collection<ValidationError> deepErrors = new HashSet<ValidationError>();
                        int i = 0;
                        for (Object element : col) {
                            Collection<ValidationError> inner = this.visit(element);
                            for (ValidationError error : inner) error.addPath(field.getName() + "[" + i + "]");
                            deepErrors.addAll(inner);
                            i++;
                        }
                        errors.addAll(deepErrors);
                    }
                    if (col.size() < collectionConstraint.minLength()) errors.add(new ValidationError(field.getName(), errorCodes[2], collectionConstraint, collection));
                    if (col.size() > collectionConstraint.maxLength()) errors.add(new ValidationError(field.getName(), errorCodes[3], collectionConstraint, collection));
                } else {
                    throw new IllegalArgumentException("The annotated element is not a collection [" + collection + "]");
                }
            }
        }
        return errors;
    }

}
TOP

Related Classes of org.internna.iwebmvc.core.validation.ValidationVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.