Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ public void testCustomConfigurationViaBeans() {
assertThat(hibernateValidatorFactory.getScriptEvaluatorFactory()).isInstanceOf(MyScriptEvaluatorFactory.class);
assertThat(hibernateValidatorFactory.getGetterPropertySelectionStrategy())
.isInstanceOf(MyGetterPropertySelectionStrategy.class);
// Waiting for https://hibernate.atlassian.net/browse/HV-1841 to be released
//assertThat(hibernateValidatorFactory.getPropertyNodeNameProvider())
// .isInstanceOf(MyPropertyNodeNameProvider.class);
assertThat(hibernateValidatorFactory.getPropertyNodeNameProvider())
.isInstanceOf(MyPropertyNodeNameProvider.class);
}

@ApplicationScoped
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import jakarta.validation.Validator;
import jakarta.validation.executable.ExecutableValidator;

import org.hibernate.validator.path.RandomAccessPath;

/**
* NOTE: this is a copy of the interceptor present in hibernate-validator-cdi.
* For now, I prefer not depending on this artifact but this might change in the
Expand Down Expand Up @@ -153,6 +155,9 @@ private String getMessage(Member member, Object[] args, Set<? extends Constraint
}

private Path.Node getLeafNode(ConstraintViolation<?> constraintViolation) {
if (constraintViolation.getPropertyPath() instanceof RandomAccessPath randomAccessPath) {
return randomAccessPath.getLeafNode();
}
Iterator<Path.Node> nodes = constraintViolation.getPropertyPath().iterator();
Path.Node leafNode = null;
while (nodes.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,52 @@
package io.quarkus.hibernate.validator.runtime.jaxrs;

import java.util.Iterator;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ElementKind;
import jakarta.validation.Path.Node;

import org.hibernate.validator.path.RandomAccessPath;
import org.jboss.resteasy.api.validation.ConstraintType;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.spi.validation.ConstraintTypeUtil;

public class ConstraintTypeUtil20 implements ConstraintTypeUtil {

@Override
public ConstraintType.Type getConstraintType(Object o) {
if (!(o instanceof ConstraintViolation)) {
throw new RuntimeException(Messages.MESSAGES.unknownObjectPassedAsConstraintViolation(o));
}
ConstraintViolation<?> v = ConstraintViolation.class.cast(o);

Iterator<Node> nodes = v.getPropertyPath().iterator();
Node firstNode = nodes.next();
public static final ConstraintTypeUtil INSTANCE = new ConstraintTypeUtil20();

switch (firstNode.getKind()) {
case BEAN:
return ConstraintType.Type.CLASS;
case CONSTRUCTOR:
case METHOD:
Node secondNode = nodes.next();
private ConstraintTypeUtil20() {
}

if (secondNode.getKind() == ElementKind.PARAMETER || secondNode.getKind() == ElementKind.CROSS_PARAMETER) {
return ConstraintType.Type.PARAMETER;
} else if (secondNode.getKind() == ElementKind.RETURN_VALUE) {
return ConstraintType.Type.RETURN_VALUE;
} else {
throw new RuntimeException(Messages.MESSAGES.unexpectedPathNodeViolation(secondNode.getKind()));
@Override
public ConstraintType.Type getConstraintType(Object o) {
if (o instanceof ConstraintViolation<?> v) {
if (v.getPropertyPath() instanceof RandomAccessPath randomAccessPath) {
switch (randomAccessPath.getRootNode().getKind()) {
case BEAN:
return ConstraintType.Type.CLASS;
case CONSTRUCTOR:
case METHOD:
Node secondNode = randomAccessPath.getNode(1);

if (secondNode.getKind() == ElementKind.PARAMETER
|| secondNode.getKind() == ElementKind.CROSS_PARAMETER) {
return ConstraintType.Type.PARAMETER;
} else if (secondNode.getKind() == ElementKind.RETURN_VALUE) {
return ConstraintType.Type.RETURN_VALUE;
} else {
throw new RuntimeException(Messages.MESSAGES.unexpectedPathNodeViolation(secondNode.getKind()));
}
case PROPERTY:
return ConstraintType.Type.PROPERTY;
case CROSS_PARAMETER:
case PARAMETER:
case RETURN_VALUE:
case CONTAINER_ELEMENT: // we shouldn't encounter these element types at the root
default:
throw new RuntimeException(
Messages.MESSAGES.unexpectedPathNode(randomAccessPath.getRootNode().getKind()));
}
case PROPERTY:
return ConstraintType.Type.PROPERTY;
case CROSS_PARAMETER:
case PARAMETER:
case RETURN_VALUE:
case CONTAINER_ELEMENT: // we shouldn't encounter these element types at the root
default:
throw new RuntimeException(Messages.MESSAGES.unexpectedPathNode(firstNode.getKind()));
}
}
throw new RuntimeException(Messages.MESSAGES.unknownObjectPassedAsConstraintViolation(o));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

import org.hibernate.validator.path.RandomAccessPath;
import org.jboss.resteasy.reactive.common.util.ServerMediaType;
import org.jboss.resteasy.reactive.server.core.CurrentRequestManager;
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;
Expand Down Expand Up @@ -57,6 +58,11 @@ private boolean hasReturnValueViolation(Set<ConstraintViolation<?>> violations)
}

private boolean isReturnValueViolation(ConstraintViolation<?> violation) {
if (violation.getPropertyPath() instanceof RandomAccessPath randomAccessPath) {
return randomAccessPath.getRootNode().getKind() == ElementKind.METHOD
&& randomAccessPath.getNode(1).getKind() == ElementKind.RETURN_VALUE;
}

Iterator<Path.Node> nodes = violation.getPropertyPath().iterator();
Path.Node firstNode = nodes.next();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.hibernate.validator.runtime.jaxrs;

import java.io.Serial;
import java.util.List;
import java.util.Set;

Expand All @@ -20,6 +21,7 @@
* while a violation on the parameters of a REST endpoint call is a client error (HTTP 400).
*/
public class ResteasyViolationExceptionImpl extends ResteasyViolationException {
@Serial
private static final long serialVersionUID = 657697354453281559L;

public ResteasyViolationExceptionImpl(final Set<? extends ConstraintViolation<?>> constraintViolations,
Expand All @@ -29,7 +31,7 @@ public ResteasyViolationExceptionImpl(final Set<? extends ConstraintViolation<?>

@Override
public ConstraintTypeUtil getConstraintTypeUtil() {
return new ConstraintTypeUtil20();
return ConstraintTypeUtil20.INSTANCE;
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<bytebuddy.version>1.17.6</bytebuddy.version> <!-- version controlled by Hibernate ORM's needs -->
<hibernate-models.version>1.0.1</hibernate-models.version> <!-- version controlled by Hibernate ORM's needs -->
<hibernate-reactive.version>3.1.3.Final</hibernate-reactive.version> <!-- highly sensitive to Hibernate ORM upgrades -->
<hibernate-validator.version>9.0.1.Final</hibernate-validator.version>
<hibernate-validator.version>9.1.0.Alpha2</hibernate-validator.version>
<hibernate-search.version>8.1.2.Final</hibernate-search.version>
<hibernate-tools.version>7.1.1.Final</hibernate-tools.version>

Expand Down