Package org.apache.bval.jsr

Source Code of org.apache.bval.jsr.GroupValidationContextImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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.apache.bval.jsr;

import org.apache.bval.BeanValidationContext;
import org.apache.bval.jsr.groups.Group;
import org.apache.bval.jsr.groups.Groups;
import org.apache.bval.jsr.resolver.CachingTraversableResolver;
import org.apache.bval.jsr.util.NodeImpl;
import org.apache.bval.jsr.util.PathImpl;
import org.apache.bval.model.MetaBean;
import org.apache.bval.model.MetaProperty;
import org.apache.bval.util.AccessStrategy;

import javax.validation.ConstraintValidator;
import javax.validation.ElementKind;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
import javax.validation.Path;
import javax.validation.TraversableResolver;
import javax.validation.ValidationException;
import javax.validation.metadata.ConstraintDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
* Description: instance per validation process, not thread-safe<br/>
*/
final class GroupValidationContextImpl<T> extends BeanValidationContext<ConstraintValidationListener<T>> implements
    GroupValidationContext<T>, MessageInterpolator.Context {

    private final MessageInterpolator messageResolver;
    private final PathImpl path;
    private final MetaBean rootMetaBean;
    private final ParameterNameProvider parameterNameProvider;

    /**
     * the groups in the sequence of validation to take place
     */
    private Groups groups;
    /**
     * the current group during the validation process
     */
    private Group currentGroup;

    private Class<?> currentOwner;

    /**
     * contains the validation constraints that have already been processed
     * during this validation routine (as part of a previous group match)
     */
    private HashSet<ConstraintValidatorIdentity> validatedConstraints = new HashSet<ConstraintValidatorIdentity>();

    private ConstraintValidation<?> constraintValidation;
    private final TraversableResolver traversableResolver;

    private Object[] parameters;
    private Object returnValue;
    private Method method;
    private Constructor<?> constructor;

    /**
     * Create a new GroupValidationContextImpl instance.
     *
     * @param listener
     * @param aMessageResolver
     * @param traversableResolver
     * @param parameterNameProvider
     * @param rootMetaBean
     */
    public GroupValidationContextImpl(ConstraintValidationListener<T> listener, MessageInterpolator aMessageResolver,
                                      TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider, MetaBean rootMetaBean) {
        // inherited variable 'validatedObjects' is of type:
        // HashMap<GraphBeanIdentity, Set<PathImpl>> in this class
        super(listener, new HashMap<GraphBeanIdentity, Set<PathImpl>>());
        this.messageResolver = aMessageResolver;
        this.traversableResolver = CachingTraversableResolver.cacheFor(traversableResolver);
        this.parameterNameProvider = parameterNameProvider;
        this.rootMetaBean = rootMetaBean;
        this.path = PathImpl.create();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setCurrentIndex(Integer index) {
        NodeImpl leaf = path.getLeafNode();
        if (leaf.getName() == null) {
            leaf.setIndex(index);
        } else {
            path.addNode(NodeImpl.atIndex(index));
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setCurrentKey(Object key) {
        NodeImpl leaf = path.getLeafNode();
        if (leaf.getName() == null) {
            leaf.setKey(key);
        } else {
            path.addNode(NodeImpl.atKey(key));
        }
    }

    public void setKind(final ElementKind type) {
        path.getLeafNode().setKind(type);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void moveDown(MetaProperty prop, AccessStrategy access) {
        moveDown(prop.getName());
        super.moveDown(prop, access);
    }

    @Override
    public void moveDown(final String prop) {
        path.addProperty(prop);
    }

    public void moveDown(final Path.Node node) {
        path.addNode(node);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void moveUp(Object bean, MetaBean metaBean) {
        NodeImpl leaf = path.getLeafNode();
        if (leaf.isInIterable() && leaf.getName() != null) {
            leaf.setName(null);
        } else {
            path.removeLeafNode();
        }
        super.moveUp(bean, metaBean); // call super!
    }

    /**
     * {@inheritDoc} Here, state equates to bean identity + group.
     */
    @SuppressWarnings("unchecked")
    @Override
    public boolean collectValidated() {

        // Combination of bean+group+owner (owner is currently ignored)
        GraphBeanIdentity gbi = new GraphBeanIdentity(getBean(), getCurrentGroup().getGroup(), getCurrentOwner());

        Set<PathImpl> validatedPathsForGBI = (Set<PathImpl>) validatedObjects.get(gbi);
        if (validatedPathsForGBI == null) {
            validatedPathsForGBI = new HashSet<PathImpl>();
            validatedObjects.put(gbi, validatedPathsForGBI);
        }

        // If any of the paths is a subpath of the current path, there is a
        // circular dependency, so return false
        for (PathImpl validatedPath : validatedPathsForGBI) {
            if (path.isSubPathOf(validatedPath)) {
                return false;
            }
        }

        // Else, add the currentPath to the set of validatedPaths
        validatedPathsForGBI.add(PathImpl.copy(path));
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public boolean collectValidated(ConstraintValidator<?, ?> constraint) {
        ConstraintValidatorIdentity cvi = new ConstraintValidatorIdentity(getBean(), getPropertyPath(), constraint);
        return this.validatedConstraints.add(cvi);
    }

    /**
     * Reset the validated constraints.
     */
    public void resetValidatedConstraints() {
        validatedConstraints.clear();
    }

    /**
     * {@inheritDoc} If an associated object is validated, add the association
     * field or JavaBeans property name and a dot ('.') as a prefix to the
     * previous rules. uses prop[index] in property path for elements in
     * to-many-relationships.
     *
     * @return the path in dot notation
     */
    public PathImpl getPropertyPath() {
        PathImpl currentPath = PathImpl.copy(path);
        if (getMetaProperty() != null) {
            currentPath.addProperty(getMetaProperty().getName());
        }
        return currentPath;
    }

    /**
     * {@inheritDoc}
     */
    public MetaBean getRootMetaBean() {
        return rootMetaBean;
    }

    /**
     * Set the Groups.
     *
     * @param groups
     */
    public void setGroups(Groups groups) {
        this.groups = groups;
    }

    /**
     * {@inheritDoc}
     */
    public Groups getGroups() {
        return groups;
    }

    public void setCurrentGroups(final Groups g) {
        groups = g;
    }

    /**
     * {@inheritDoc}
     */
    public Group getCurrentGroup() {
        return currentGroup;
    }

    /**
     * {@inheritDoc}
     */
    public void setCurrentGroup(Group currentGroup) {
        this.currentGroup = currentGroup;
    }

    /**
     * {@inheritDoc}
     */
    public void setConstraintValidation(ConstraintValidation<?> constraint) {
        constraintValidation = constraint;
    }

    /**
     * {@inheritDoc}
     */
    public ConstraintValidation<?> getConstraintValidation() {
        return constraintValidation;
    }

    /**
     * {@inheritDoc}
     */
    public ConstraintDescriptor<?> getConstraintDescriptor() {
        return constraintValidation;
    }

    /**
     * {@inheritDoc}
     */
    public Object getValidatedValue() {
        if (getMetaProperty() != null) {
            return getPropertyValue(constraintValidation.getAccess());
        } else {
            return getBean();
        }
    }

    public <T> T unwrap(Class<T> type) {
        if (type.isInstance(this)) {
            return type.cast(this);
        }
        throw new ValidationException("Type " + type + " not supported");
    }

    /**
     * {@inheritDoc}
     */
    public MessageInterpolator getMessageResolver() {
        return messageResolver;
    }

    /**
     * {@inheritDoc}
     */
    public TraversableResolver getTraversableResolver() {
        return traversableResolver;
    }

    /**
     * {@inheritDoc}
     */
    public Class<?> getCurrentOwner() {
        return this.currentOwner;
    }

    /**
     * {@inheritDoc}
     */
    public void setCurrentOwner(Class<?> currentOwner) {
        this.currentOwner = currentOwner;
    }

    public ElementKind getElementKind() {
        return path.getLeafNode().getKind();
    }

    public Object getReturnValue() {
        return returnValue;
    }

    public Object[] getParameters() {
        return parameters;
    }

    public void setParameters(final Object[] parameters) {
        this.parameters = parameters;
    }

    public void setReturnValue(final Object returnValue) {
        this.returnValue = returnValue;
    }

    public ParameterNameProvider getParameterNameProvider() {
        return parameterNameProvider;
    }

    public void setMethod(final Method method) {
        this.method = method;
    }

    public Method getMethod() {
        return method;
    }

    public Constructor<?> getConstructor() {
        return constructor;
    }

    public void setConstructor(final Constructor<?> constructor) {
        this.constructor = constructor;
    }
}
TOP

Related Classes of org.apache.bval.jsr.GroupValidationContextImpl

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.