package org.hibernate.validator.internal.engine.valuecontext;
import java.lang.reflect.TypeVariable;
import jakarta.validation.groups.Default;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.hibernate.validator.internal.engine.valueextraction.AnnotatedObject;
import org.hibernate.validator.internal.engine.valueextraction.ArrayElement;
import org.hibernate.validator.internal.metadata.facets.Cascadable;
import org.hibernate.validator.internal.metadata.facets.Validatable;
import org.hibernate.validator.internal.metadata.location.ConstraintLocation;
import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind;
import org.hibernate.validator.internal.util.ExecutableParameterNameProvider;
import org.hibernate.validator.internal.util.TypeVariables;
public class ValueContext<T, V> {
private final ExecutableParameterNameProvider parameterNameProvider;
private final T currentBean;
private PathImpl propertyPath;
private Class<?> currentGroup;
private V currentValue;
private final Validatable currentValidatable;
private ConstraintLocationKind constraintLocationKind;
ValueContext(ExecutableParameterNameProvider parameterNameProvider, T currentBean, Validatable validatable, PathImpl propertyPath) {
this.parameterNameProvider = parameterNameProvider;
this.currentBean = currentBean;
this.currentValidatable = validatable;
this.propertyPath = propertyPath;
}
public final PathImpl getPropertyPath() {
return propertyPath;
}
public final Class<?> getCurrentGroup() {
return currentGroup;
}
public final T getCurrentBean() {
return currentBean;
}
public Validatable getCurrentValidatable() {
return currentValidatable;
}
public final Object getCurrentValidatedValue() {
return currentValue;
}
public final void appendNode(Cascadable node) {
PathImpl newPath = PathImpl.createCopy( propertyPath );
node.appendTo( newPath );
propertyPath = newPath;
}
public final void appendNode(ConstraintLocation location) {
PathImpl newPath = PathImpl.createCopy( propertyPath );
location.appendTo( parameterNameProvider, newPath );
propertyPath = newPath;
}
public final void appendTypeParameterNode(String nodeName) {
PathImpl newPath = PathImpl.createCopy( propertyPath );
newPath.addContainerElementNode( nodeName );
propertyPath = newPath;
}
public final void markCurrentPropertyAsIterable() {
propertyPath.makeLeafNodeIterable();
}
public final void markCurrentPropertyAsIterableAndSetKey(Object key) {
propertyPath.makeLeafNodeIterableAndSetMapKey( key );
}
public final void markCurrentPropertyAsIterableAndSetIndex(Integer index) {
propertyPath.makeLeafNodeIterableAndSetIndex( index );
}
public final void setTypeParameter(Class<?> containerClass, Integer typeParameterIndex) {
if ( containerClass == null ) {
return;
}
propertyPath.setLeafNodeTypeParameter( containerClass, typeParameterIndex );
}
public final void setCurrentGroup(Class<?> currentGroup) {
this.currentGroup = currentGroup;
}
public final void setCurrentValidatedValue(V currentValue) {
propertyPath.setLeafNodeValueIfRequired( currentValue );
this.currentValue = currentValue;
}
public final boolean validatingDefault() {
return getCurrentGroup() != null && getCurrentGroup().getName().equals( Default.class.getName() );
}
public final ConstraintLocationKind getConstraintLocationKind() {
return constraintLocationKind;
}
public final void setConstraintLocationKind(ConstraintLocationKind constraintLocationKind) {
this.constraintLocationKind = constraintLocationKind;
}
public final ValueState<V> getCurrentValueState() {
return new ValueState<V>( propertyPath, currentValue );
}
public final void resetValueState(ValueState<V> valueState) {
this.propertyPath = valueState.getPropertyPath();
this.currentValue = valueState.getCurrentValue();
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "ValueContext" );
sb.append( "{currentBean=" ).append( currentBean );
sb.append( ", propertyPath=" ).append( propertyPath );
sb.append( ", currentGroup=" ).append( currentGroup );
sb.append( ", currentValue=" ).append( currentValue );
sb.append( ", constraintLocationKind=" ).append( constraintLocationKind );
sb.append( '}' );
return sb.toString();
}
public Object getValue(Object parent, ConstraintLocation location) {
return location.getValue( parent );
}
public static class ValueState<V> {
private final PathImpl propertyPath;
private final V currentValue;
ValueState(PathImpl propertyPath, V currentValue) {
this.propertyPath = propertyPath;
this.currentValue = currentValue;
}
public PathImpl getPropertyPath() {
return propertyPath;
}
public V getCurrentValue() {
return currentValue;
}
}
}