Skip to content
Permalink
Browse files
no implicit groups on interfaces; retain elsewhere
  • Loading branch information
mbenson committed Oct 16, 2018
1 parent 61709b4 commit 1b4db6d8864bc77c5d01bea171d3a6f8e9a0c29e
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 110 deletions.
@@ -87,7 +87,6 @@ private static <T> Set<T> set(Supplier<T[]> array) {

public ConstraintD(A annotation, Scope scope, Meta<?> meta, ApacheValidatorFactory validatorFactory) {
this.annotation = Validate.notNull(annotation, "annotation");
validatorFactory.getAnnotationsManager().validateConstraintDefinition(annotation.annotationType());
this.scope = Validate.notNull(scope, "scope");
this.meta = Validate.notNull(meta, "meta");

@@ -50,13 +50,11 @@ public static <E extends ExecutableDescriptor> boolean isConstrained(E descripto
private final ApacheValidatorFactory validatorFactory;
private final ConcurrentMap<Class<?>, BeanD<?>> beanDescriptors = new ConcurrentHashMap<>();
private final ReflectionBuilder reflectionBuilder;
private final MetadataReader metadataReader;

public DescriptorManager(ApacheValidatorFactory validatorFactory) {
super();
this.validatorFactory = Validate.notNull(validatorFactory, "validatorFactory");
this.reflectionBuilder = new ReflectionBuilder(validatorFactory);
this.metadataReader = new MetadataReader(validatorFactory);
}

public <T> BeanDescriptor getBeanDescriptor(Class<T> beanClass) {
@@ -66,7 +64,9 @@ public <T> BeanDescriptor getBeanDescriptor(Class<T> beanClass) {
if (beanDescriptors.containsKey(beanClass)) {
return beanDescriptors.get(beanClass);
}
final BeanD<T> beanD = new BeanD<>(metadataReader.forBean(beanClass, builder(beanClass)));
final MetadataReader.ForBean<T> reader =
new MetadataReader(validatorFactory, beanClass).forBean(builder(beanClass));
final BeanD<T> beanD = new BeanD<>(reader);
@SuppressWarnings("unchecked")
final BeanD<T> result =
Optional.ofNullable((BeanD<T>) beanDescriptors.putIfAbsent(beanClass, beanD)).orElse(beanD);
@@ -50,15 +50,19 @@
import javax.validation.metadata.Scope;

import org.apache.bval.jsr.ApacheValidatorFactory;
import org.apache.bval.jsr.ConstraintAnnotationAttributes;
import org.apache.bval.jsr.groups.GroupConversion;
import org.apache.bval.jsr.groups.GroupsComputer;
import org.apache.bval.jsr.metadata.ContainerElementKey;
import org.apache.bval.jsr.metadata.EmptyBuilder;
import org.apache.bval.jsr.metadata.Meta;
import org.apache.bval.jsr.metadata.MetadataBuilder;
import org.apache.bval.jsr.metadata.Signature;
import org.apache.bval.jsr.util.Methods;
import org.apache.bval.jsr.util.ToUnmodifiable;
import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
import org.apache.bval.util.Exceptions;
import org.apache.bval.util.ObjectUtils;
import org.apache.bval.util.Validate;
import org.apache.bval.util.reflection.Reflection;

@@ -75,16 +79,43 @@ class MetadataReader {
}

Set<ConstraintD<?>> getConstraints() {
return builder.getConstraintsByScope(meta).entrySet().stream()
.flatMap(e -> describe(e.getValue(), e.getKey(), meta)).collect(ToUnmodifiable.set());
return builder.getConstraintDeclarationMap(meta).entrySet().stream().flatMap(e -> {
final Meta<E> m = e.getKey();
final Class<?> declaredBy = m.getDeclaringClass();
final Scope scope = declaredBy.equals(beanClass) ? Scope.LOCAL_ELEMENT : Scope.HIERARCHY;
return Stream.of(e.getValue())
.peek(
c -> validatorFactory.getAnnotationsManager().validateConstraintDefinition(c.annotationType()))
.map(c -> rewriteConstraint(c, declaredBy))
.map(c -> new ConstraintD<>(c, scope, m, validatorFactory));
}).collect(ToUnmodifiable.set());
}

ApacheValidatorFactory getValidatorFactory() {
return validatorFactory;
}

private Stream<ConstraintD<?>> describe(Annotation[] constraints, Scope scope, Meta<?> meta) {
return Stream.of(constraints).map(c -> new ConstraintD<>(c, scope, meta, validatorFactory));
private <A extends Annotation> A rewriteConstraint(A constraint, Class<?> declaredBy) {
boolean mustRewrite = false;
Class<?>[] groups =
ConstraintAnnotationAttributes.GROUPS.analyze(constraint.annotationType()).read(constraint);
if (groups.length == 0) {
mustRewrite = true;
groups = GroupsComputer.DEFAULT_GROUP;
}
if (!(declaredBy.equals(beanClass) || beanClass.isInterface())) {
if (ObjectUtils.arrayContains(groups, Default.class)
&& !ObjectUtils.arrayContains(groups, declaredBy)) {
mustRewrite = true;
groups = ObjectUtils.arrayAdd(groups, declaredBy);
}
}
if (mustRewrite) {
final AnnotationProxyBuilder<A> builder = new AnnotationProxyBuilder<A>(constraint);
builder.setGroups(groups);
return builder.createAnnotation();
}
return constraint;
}
}

@@ -316,13 +347,16 @@ List<String> getParameterNames(ParameterNameProvider parameterNameProvider, Cons
}

private final ApacheValidatorFactory validatorFactory;
private final Class<?> beanClass;

MetadataReader(ApacheValidatorFactory validatorFactory) {
MetadataReader(ApacheValidatorFactory validatorFactory, Class<?> beanClass) {
super();
this.validatorFactory = Validate.notNull(validatorFactory, "validatorFactory");
this.beanClass = Validate.notNull(beanClass, "beanClass");
}

<T> MetadataReader.ForBean<T> forBean(Class<T> beanClass, MetadataBuilder.ForBean<T> builder) {
return new MetadataReader.ForBean<>(new Meta.ForClass<>(beanClass), builder);
@SuppressWarnings("unchecked")
<T> MetadataReader.ForBean<T> forBean(MetadataBuilder.ForBean<T> builder) {
return new MetadataReader.ForBean<>(new Meta.ForClass<>((Class<T>) beanClass), builder);
}
}
@@ -133,11 +133,11 @@ private Stream<Frame<D>> unwrap(ValidateUnwrappedValue valueUnwrapping) {

private Stream<ConstraintD<?>> constraintsFor(Class<?> group) {
return descriptor.getConstraintDescriptors().stream().<ConstraintD<?>> map(ConstraintD.class::cast)
.filter(c -> Stream.of(group).anyMatch(t -> {
.filter(c -> {
final Set<Class<?>> constraintGroups = c.getGroups();
return constraintGroups.contains(t)
|| constraintGroups.contains(Default.class) && c.getDeclaringClass().isAssignableFrom(t);
}));
return constraintGroups.contains(group)
|| constraintGroups.contains(Default.class) && c.getDeclaringClass().isAssignableFrom(group);
});
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -39,7 +39,6 @@

import javax.validation.ElementKind;
import javax.validation.ParameterNameProvider;
import javax.validation.metadata.Scope;

import org.apache.bval.jsr.ApacheValidatorFactory;
import org.apache.bval.jsr.groups.GroupConversion;
@@ -71,7 +70,8 @@ <K, D> Map<K, D> merge(Function<DELEGATE, Map<K, D>> toMap, Function<List<D>, D>
}

<K, D> Map<K, D> merge(Function<DELEGATE, Map<K, D>> toMap, BiFunction<K, List<D>, D> merge) {
final List<Map<K, D>> maps = delegates.stream().map(toMap).collect(Collectors.toList());
final List<Map<K, D>> maps =
delegates.stream().map(toMap).filter(m -> !m.isEmpty()).collect(Collectors.toList());

final Function<? super K, ? extends D> valueMapper = k -> {
final List<D> mappedDelegates =
@@ -140,8 +140,8 @@ public Map<Signature, MetadataBuilder.ForExecutable<Method>> getMethods(Meta<Cla
}

@Override
public Map<Scope, Annotation[]> getConstraintsByScope(Meta<E> meta) {
return CompositeBuilder.this.getConstraintsByScope(this, meta);
public Map<Meta<E>, Annotation[]> getConstraintDeclarationMap(Meta<E> meta) {
return CompositeBuilder.this.getConstraintDeclarationMap(this, meta);
}

@Override
@@ -263,9 +263,9 @@ protected final <E extends Executable> List<Meta<Parameter>> getMetaParameters(M
.mapToObj(n -> new Meta.ForParameter(parameters[n], parameterNames.get(n))).collect(Collectors.toList());
}

protected <E extends AnnotatedElement> Map<Scope, Annotation[]> getConstraintsByScope(
protected <E extends AnnotatedElement> Map<Meta<E>, Annotation[]> getConstraintDeclarationMap(
CompositeBuilder.ForElement<? extends MetadataBuilder.ForElement<E>, E> composite, Meta<E> meta) {
return Collections.singletonMap(Scope.LOCAL_ELEMENT, composite.getDeclaredConstraints(meta));
return Collections.singletonMap(meta, composite.getDeclaredConstraints(meta));
}

protected <T> List<Class<?>> getGroupSequence(CompositeBuilder.ForClass<T> composite, Meta<Class<T>> meta) {
@@ -26,7 +26,6 @@
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@@ -37,10 +36,10 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import javax.validation.ElementKind;
import javax.validation.ParameterNameProvider;
import javax.validation.metadata.Scope;

import org.apache.bval.jsr.ApacheValidatorFactory;
import org.apache.bval.jsr.groups.GroupConversion;
@@ -314,20 +313,16 @@ public <T> MetadataBuilder.ForBean<T> forBean(Class<T> beanClass) {
}

@Override
protected <E extends AnnotatedElement> Map<Scope, Annotation[]> getConstraintsByScope(
protected <E extends AnnotatedElement> Map<Meta<E>, Annotation[]> getConstraintDeclarationMap(
CompositeBuilder.ForElement<? extends MetadataBuilder.ForElement<E>, E> composite, Meta<E> meta) {

final Iterator<? extends MetadataBuilder.ForElement<E>> iter = composite.delegates.iterator();

final Map<Scope, Annotation[]> result = new EnumMap<>(Scope.class);
result.put(Scope.LOCAL_ELEMENT, iter.next().getDeclaredConstraints(meta));
@SuppressWarnings("unchecked")
final Function<MetadataBuilder.ForElement<E>, Meta<E>> keyMapper =
d -> Optional.of(d).filter(HierarchyDelegate.class::isInstance).map(HierarchyDelegate.class::cast)
.map(HierarchyDelegate::getHierarchyElement).orElse(meta);

if (iter.hasNext()) {
final List<Annotation> hierarchyConstraints = new ArrayList<>();
iter.forEachRemaining(d -> Collections.addAll(hierarchyConstraints, d.getDeclaredConstraints(meta)));
result.put(Scope.HIERARCHY, hierarchyConstraints.toArray(new Annotation[hierarchyConstraints.size()]));
}
return result;
return composite.delegates.stream().collect(Collectors.toMap(keyMapper, d -> d.getDeclaredConstraints(meta),
(u, v) -> Stream.of(u, v).flatMap(Stream::of).toArray(Annotation[]::new), LinkedHashMap::new));
}

@Override
@@ -29,8 +29,6 @@
import java.util.Map;
import java.util.Set;

import javax.validation.metadata.Scope;

import org.apache.bval.jsr.groups.GroupConversion;

/**
@@ -65,8 +63,8 @@ default boolean isEmpty() {

Annotation[] getDeclaredConstraints(Meta<E> meta);

default Map<Scope, Annotation[]> getConstraintsByScope(Meta<E> meta) {
return Collections.singletonMap(Scope.LOCAL_ELEMENT, getDeclaredConstraints(meta));
default Map<Meta<E>, Annotation[]> getConstraintDeclarationMap(Meta<E> meta) {
return Collections.singletonMap(meta, getDeclaredConstraints(meta));
}
}

0 comments on commit 1b4db6d

Please sign in to comment.