// Copyright © 2015 HSL <https://www.hsl.fi>
// This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses.
package fi.hsl.parkandride.core.domain;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import javax.annotation.Nullable;
import javax.validation.ConstraintViolation;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.collect.Maps.filterKeys;
import static fi.hsl.parkandride.core.domain.PropertyPathTranslator.translate;
import static java.util.stream.Collectors.toList;
public class Violation {
private static final Set<String> EXCLUDED_ARGUMENTS = ImmutableSet.of("message", "groups", "payload");
public final String type;
public final Map<String, Object> args;
public final String path;
public final String message;
public Violation(String type) {
this(type, ImmutableMap.of(), "", type);
}
public Violation(String type, String path, String message) {
this(type, ImmutableMap.of(), path, message);
}
public Violation(String type, Map<String, Object> args, String path, String message) {
this.type = type;
this.args = ImmutableMap.copyOf(args);
this.path = path;
this.message = message;
}
public Violation(ConstraintViolation cv) {
this(getType(cv), getArgs(cv), getPath(cv), cv.getMessage());
}
private static Map<String, Object> getArgs(ConstraintViolation<?> cv) {
// NOTE: This supports only simple types, not annotation parameters!
return filterKeys(cv.getConstraintDescriptor().getAttributes(), new Predicate<String>() {
@Override
public boolean apply(@Nullable String input) {
return !EXCLUDED_ARGUMENTS.contains(input);
}
});
}
private static String getPath(ConstraintViolation cv) {
return translate(cv.getPropertyPath().toString());
}
private static String getType(ConstraintViolation constraintViolation) {
return constraintViolation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName();
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("type", type)
.add("args", args)
.add("path", path)
.add("message", message)
.toString();
}
public static List<Violation> withPathPrefix(String pathPrefix, List<Violation> violations) {
return violations.stream()
.map(v -> new Violation(v.type, v.args, pathPrefix + v.path, v.message))
.collect(toList());
}
}