Skip to content
Permalink
Browse files
revamp custom constraint building code for TCK progress/spec compliance
  • Loading branch information
mbenson committed Oct 16, 2018
1 parent 860ff19 commit 54dab69636b0ebd4a663039680fb7036aa0cb922
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 207 deletions.
@@ -24,6 +24,7 @@
import javax.validation.ClockProvider;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.ElementKind;
import javax.validation.MessageInterpolator;
import javax.validation.ValidationException;
import javax.validation.metadata.ConstraintDescriptor;
@@ -43,10 +44,12 @@
import org.apache.bval.util.Validate;

public class ConstraintValidatorContextImpl<T> implements ConstraintValidatorContext, MessageInterpolator.Context {
private class ConstraintViolationBuilderImpl implements ConstraintValidatorContext.ConstraintViolationBuilder {
public class ConstraintViolationBuilderImpl implements ConstraintValidatorContext.ConstraintViolationBuilder {
private final String template;
private final PathImpl path;

private boolean complete;

ConstraintViolationBuilderImpl(String template, PathImpl path) {
this.template = template;
this.path = path;
@@ -57,29 +60,22 @@ private class ConstraintViolationBuilderImpl implements ConstraintValidatorConte
*/
@Override
public NodeBuilderDefinedContext addNode(String name) {
PathImpl p;
if (path.isRootPath()) {
p = PathImpl.create();
p.getLeafNode().setName(name);
} else {
p = PathImpl.copy(path);
p.addNode(new NodeImpl.PropertyNodeImpl(name));
}
return new NodeBuilderDefinedContextImpl(ConstraintValidatorContextImpl.this, template, p);
return new NodeBuilderDefinedContextImpl(extensiblePath().addProperty(name), this);
}

@Override
public NodeBuilderCustomizableContext addPropertyNode(String name) {
return new NodeBuilderCustomizableContextImpl(ConstraintValidatorContextImpl.this, template, path, name);
return new NodeBuilderCustomizableContextImpl(extensiblePath(), name, this);
}

@Override
public LeafNodeBuilderCustomizableContext addBeanNode() {
return new LeafNodeBuilderCustomizableContextImpl(ConstraintValidatorContextImpl.this, template, path);
return new LeafNodeBuilderCustomizableContextImpl(extensiblePath(), this);
}

@Override
public NodeBuilderDefinedContext addParameterNode(int index) {
ofLegalState();
Exceptions.raiseUnless(frame.descriptor instanceof CrossParameterDescriptor, ValidationException::new,
"Cannot add parameter node for %s", f -> f.args(frame.descriptor.getClass().getName()));

@@ -88,28 +84,52 @@ public NodeBuilderDefinedContext addParameterNode(int index) {

final String parameterName = crossParameter.getParent().getParameterDescriptors().get(index).getName();

final NodeImpl node = new NodeImpl.ParameterNodeImpl(parameterName, index);
if (!path.isRootPath()) {
path.removeLeafNode();
}
path.addNode(node);
return new NodeBuilderDefinedContextImpl(ConstraintValidatorContextImpl.this, template, path);
path.removeLeafNode();
return new NodeBuilderDefinedContextImpl(path.addNode(new NodeImpl.ParameterNodeImpl(parameterName, index)),
this);
}

/**
* {@inheritDoc}
*/
@Override
public ConstraintValidatorContext addConstraintViolation() {
addError(template, path);
return addConstraintViolation(path);
}

public synchronized ConstraintViolationBuilderImpl ofLegalState() {
Validate.validState(!complete, "#addConstraintViolation() already called");
return this;
}

public ConstraintValidatorContext addConstraintViolation(PathImpl p) {
synchronized (this) {
ofLegalState();
complete = true;
}
addError(template, p);
return ConstraintValidatorContextImpl.this;
}

@Override
public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name,
Class<?> containerType, Integer typeArgumentIndex) {
return new ContainerElementNodeBuilderCustomizableContextImpl(ConstraintValidatorContextImpl.this, template,
path, name, containerType, typeArgumentIndex);
ofLegalState();
return new ContainerElementNodeBuilderCustomizableContextImpl(extensiblePath(), name,
containerType, typeArgumentIndex, this);
}

private PathImpl extensiblePath() {
if (path.isRootPath()) {
return PathImpl.create();
}
final PathImpl result = PathImpl.copy(path);
final NodeImpl leafNode = result.getLeafNode();
if (leafNode.getKind() == ElementKind.BEAN
&& !(leafNode.isInIterable() || leafNode.getContainerClass() != null)) {
result.removeLeafNode();
}
return result;
}
}

@@ -153,11 +173,6 @@ public <U> U unwrap(Class<U> type) {
}
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public void addError(String messageTemplate, PathImpl propertyPath) {
violations.get().add(((ValidationJob) frame.getJob()).createViolation(messageTemplate, this, propertyPath));
}

ValidationJob<T>.Frame<?> getFrame() {
return frame;
}
@@ -181,4 +196,9 @@ public ConstraintDescriptor<?> getConstraintDescriptor() {
public Object getValidatedValue() {
return frame.context.getValue();
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private void addError(String messageTemplate, PathImpl propertyPath) {
violations.get().add(((ValidationJob) frame.getJob()).createViolation(messageTemplate, this, propertyPath));
}
}
@@ -162,9 +162,8 @@ Object getBean() {

@Override
protected Frame<?> computeBaseFrame() {
final PathImpl cp = createBasePath();
cp.addNode(new NodeImpl.CrossParameterNodeImpl());
return new ParametersFrame(describe(), new GraphContext(validatorContext, cp, parameterValues));
return new ParametersFrame(describe(), new GraphContext(validatorContext,
createBasePath().addNode(new NodeImpl.CrossParameterNodeImpl()), parameterValues));
}

@Override
@@ -130,11 +130,8 @@ Object getBean() {

@Override
protected Frame<?> computeBaseFrame() {
final PathImpl path = createBasePath();
path.addNode(new NodeImpl.ReturnValueNodeImpl());

return createBaseFrame((ReturnValueD<?, ?>) describe().getReturnValueDescriptor(),
new GraphContext(validatorContext, path, returnValue));
return createBaseFrame((ReturnValueD<?, ?>) describe().getReturnValueDescriptor(), new GraphContext(
validatorContext, createBasePath().addNode(new NodeImpl.ReturnValueNodeImpl()), returnValue));
}

@Override
@@ -252,13 +252,16 @@ private Stream<Class<?>> expand(Class<?> group) {
}

public class BeanFrame<B> extends Frame<BeanD<B>> {
private final GraphContext realContext;

BeanFrame(GraphContext context) {
this(null, context);
}

BeanFrame(Frame<?> parent, GraphContext context) {
super(parent, getBeanDescriptor(context.getValue()), context);
super(parent, getBeanDescriptor(context.getValue()),
context.child(context.getPath().addBean(), context.getValue()));
this.realContext = context;
}

@Override
@@ -282,7 +285,7 @@ private Stream<Frame<?>> propertyFrames() {
final TraversableResolver traversableResolver = validatorContext.getTraversableResolver();

final Stream<PropertyD<?>> reachableProperties = properties.filter(d -> {
final PathImpl p = context.getPath();
final PathImpl p = realContext.getPath();
p.addProperty(d.getPropertyName());
try {
return traversableResolver.isReachable(context.getValue(), p.removeLeafNode(), getRootBeanClass(),
@@ -294,7 +297,7 @@ private Stream<Frame<?>> propertyFrames() {
}
});
return reachableProperties.flatMap(
d -> d.read(context).filter(context -> !context.isRecursive()).map(child -> propertyFrame(d, child)));
d -> d.read(realContext).filter(context -> !context.isRecursive()).map(child -> propertyFrame(d, child)));
}
}

@@ -28,50 +28,40 @@

public class ContainerElementNodeBuilderCustomizableContextImpl
implements ContainerElementNodeBuilderCustomizableContext {
private final ConstraintValidatorContextImpl<?> context;
private final String template;
private final PathImpl path;
private NodeImpl node;
private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;

public ContainerElementNodeBuilderCustomizableContextImpl(ConstraintValidatorContextImpl<?> context, String template,
PathImpl path, String name, Class<?> containerType, Integer typeArgumentIndex) {
public ContainerElementNodeBuilderCustomizableContextImpl(PathImpl path, String name, Class<?> containerType,
Integer typeArgumentIndex, ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
super();
this.context = context;
this.path = path;
this.template = template;
this.node = new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex);
this.builder = builder.ofLegalState();
this.path = path.addNode(new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex));
}

@Override
public ContainerElementNodeContextBuilder inIterable() {
node.setInIterable(true);
return new ContainerElementNodeContextBuilderImpl(context, template, path, node);
return new ContainerElementNodeContextBuilderImpl(path, builder);
}

@Override
public NodeBuilderCustomizableContext addPropertyNode(String name) {
path.addNode(node);
return new NodeBuilderCustomizableContextImpl(context, template, path, name);
return new NodeBuilderCustomizableContextImpl(path, name, builder);
}

@Override
public LeafNodeBuilderCustomizableContext addBeanNode() {
path.addNode(node);
return new LeafNodeBuilderCustomizableContextImpl(context, template, path);
return new LeafNodeBuilderCustomizableContextImpl(path, builder);
}

@Override
public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
Integer typeArgumentIndex) {
path.addNode(node);
node = new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex);
path.addNode(new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex));
return this;
}

@Override
public ConstraintValidatorContext addConstraintViolation() {
path.addNode(node);
context.addError(template, path);
return context;
return builder.addConstraintViolation(path);
}
}
@@ -27,39 +27,35 @@
import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;

public class ContainerElementNodeBuilderDefinedContextImpl implements ContainerElementNodeBuilderDefinedContext {
private final ConstraintValidatorContextImpl<?> context;
private final String template;
private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
private final PathImpl path;

ContainerElementNodeBuilderDefinedContextImpl(ConstraintValidatorContextImpl<?> context, String template,
PathImpl path) {
ContainerElementNodeBuilderDefinedContextImpl(PathImpl path,
ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
super();
this.context = context;
this.template = template;
this.path = path;
this.builder = builder.ofLegalState();
}

@Override
public NodeBuilderCustomizableContext addPropertyNode(String name) {
return new NodeBuilderCustomizableContextImpl(context, template, path, name);
return new NodeBuilderCustomizableContextImpl(path, name, builder);
}

@Override
public LeafNodeBuilderCustomizableContext addBeanNode() {
return new LeafNodeBuilderCustomizableContextImpl(context, template, path);
return new LeafNodeBuilderCustomizableContextImpl(path, builder);
}

@Override
public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
Integer typeArgumentIndex) {
return new ContainerElementNodeBuilderCustomizableContextImpl(context, name, path, name, containerType,
typeArgumentIndex);
return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
builder);
}

@Override
public ConstraintValidatorContext addConstraintViolation() {
context.addError(template, path);
return context;
return builder.addConstraintViolation(path);
}

}
@@ -28,58 +28,48 @@
import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;

public class ContainerElementNodeContextBuilderImpl implements ContainerElementNodeContextBuilder {
private final ConstraintValidatorContextImpl<?> context;
private final String template;
private final PathImpl path;
private final NodeImpl node;
private ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;

ContainerElementNodeContextBuilderImpl(ConstraintValidatorContextImpl<?> context, String template,
PathImpl path, NodeImpl node) {
ContainerElementNodeContextBuilderImpl(PathImpl path,
ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
super();
this.context = context;
this.template = template;
this.builder = builder.ofLegalState();
this.path = path;
this.node = node;
path.getLeafNode().inIterable();
}

@Override
public ContainerElementNodeBuilderDefinedContext atKey(Object key) {
node.setKey(key);
path.addNode(node);
return new ContainerElementNodeBuilderDefinedContextImpl(context, template, path);
path.getLeafNode().setKey(key);
return new ContainerElementNodeBuilderDefinedContextImpl(path, builder);
}

@Override
public ContainerElementNodeBuilderDefinedContext atIndex(Integer index) {
node.setIndex(index);
path.addNode(node);
return new ContainerElementNodeBuilderDefinedContextImpl(context, template, path);
path.getLeafNode().setIndex(index);
return new ContainerElementNodeBuilderDefinedContextImpl(path, builder);
}

@Override
public NodeBuilderCustomizableContext addPropertyNode(String name) {
path.addNode(node);
return new NodeBuilderCustomizableContextImpl(context, name, path, name);
return new NodeBuilderCustomizableContextImpl(path, name, builder);
}

@Override
public LeafNodeBuilderCustomizableContext addBeanNode() {
path.addNode(node);
return new LeafNodeBuilderCustomizableContextImpl(context, template, path);
return new LeafNodeBuilderCustomizableContextImpl(path, builder);
}

@Override
public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
Integer typeArgumentIndex) {
path.addNode(node);
return new ContainerElementNodeBuilderCustomizableContextImpl(context, template, path, name, containerType,
typeArgumentIndex);
return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
builder);
}

@Override
public ConstraintValidatorContext addConstraintViolation() {
context.addError(template, path);
return context;
return builder.addConstraintViolation(path);
}

}

0 comments on commit 54dab69

Please sign in to comment.