private void addNotNullViolation(List<ConstraintViolation> violations, Schema schema, List<PathNode> fieldPath) { NotNullConstraint constraint = NotNullConstraint.get(); ConstraintViolation violation = new ConstraintViolation(schema, fieldPath, constraint, null); violations.add(violation); }
pathTokens.add(constraint.getDescription().getName()); pathTokens.add(schema.getName()); for (PathNode node : path) { if (locale != null && Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) { return constraint.getErrorMessage(invalidValue, locale); } else { return getMessage(Locale.ENGLISH);
@Override public final String toString() { return getDescription().toString(); }
@Override protected void writeEntityBody(Constraint constraint, JsonGenerator jg) throws IOException { Description description = constraint.getDescription(); jg.writeStringField("name", description.getName()); // constraint parameters jg.writeObjectFieldStart("parameters"); for (Map.Entry<String, Serializable> param : description.getParameters().entrySet()) { jg.writeStringField(param.getKey(), param.getValue().toString()); } jg.writeEndObject(); }
@Override public String getErrorMessage(Object invalidValue, Locale locale) { // test whether there's a custom translation for this field constraint specific translation // the expected key is label.schema.constraint.violation.[ConstraintName] // follow the AbstractConstraint behavior otherwise List<String> pathTokens = new ArrayList<>(); pathTokens.add(MESSAGES_KEY); pathTokens.add(EnumConstraint.NAME); String key = StringUtils.join(pathTokens, '.'); Object[] params = new Object[] { StringUtils.join(getPossibleValues(), ", ") }; Locale computedLocale = locale != null ? locale : Constraint.MESSAGES_DEFAULT_LANG; String message = getMessageString(MESSAGES_BUNDLE, key, params, computedLocale); if (message != null && !message.trim().isEmpty() && !key.equals(message)) { // use a custom constraint message if there's one return message; } else { // follow AbstractConstraint behavior otherwise return super.getErrorMessage(invalidValue, computedLocale); } }
@Override public String getErrorMessage(Object invalidValue, Locale locale) { // test whether there's a custom translation for this field constraint specific translation // the expected key is label.schema.constraint.violation.[ConstraintName] // follow the AbstractConstraint behavior otherwise List<String> pathTokens = new ArrayList<String>(); pathTokens.add(MESSAGES_KEY); pathTokens.add(PatternConstraint.NAME); String key = StringUtils.join(pathTokens, '.'); Object[] params = new Object[] { getPattern() }; Locale computedLocale = locale != null ? locale : Constraint.MESSAGES_DEFAULT_LANG; String message = getMessageString(MESSAGES_BUNDLE, key, params, computedLocale); if (message != null && !message.trim().isEmpty() && !key.equals(message)) { // use a custom constraint message if there's one return message; } else { // follow AbstractConstraint behavior otherwise return super.getErrorMessage(invalidValue, computedLocale); } }
protected boolean validateConstraints(Object object) { if (constraints != null) { for (Constraint constraint : constraints) { if (!constraint.validate(object)) { return false; } } } return true; }
/** * Here, value is : <br> * name = {@value #NAME}. <br> * parameters is empty */ @Override public Description getDescription() { Map<String, Serializable> params = new HashMap<String, Serializable>(); return new Description(NotNullConstraint.NAME, params); }
/** * Use null value to disable a bound. * <p> * Bounds could be any object having toString representating a number. * </p> * * @param min The lower bound of the interval * @param includingMin true if the lower bound is included in the interval * @param max The upper bound of the interval * @param includingMax true if the upper bound is included in the interval */ public NumericIntervalConstraint(Object min, boolean includingMin, Object max, boolean includingMax) { this.min = ConstraintUtils.objectToBigDecimal(min); this.includingMin = includingMin; this.max = ConstraintUtils.objectToBigDecimal(max); this.includingMax = includingMax; }
/** * Use null value to disable a bound. * <p> * Bounds could be any {@link Date} or {@link Calendar}. Bounds also support {@link Number} types whose long value * is recognised as number of milliseconds since January 1, 1970, 00:00:00 GMT. Bounds finally supports String * having YYYY-MM-DD format. * </p> * <p> * Invalid bound (wrong format) would be ignored with log warning. * </p> * * @param minDate The lower bound of the interval * @param includingMin true if the lower bound is included in the interval * @param maxDate The upper bound of the interval * @param includingMax true if the upper bound is included in the interval */ public DateIntervalConstraint(Object minDate, boolean includingMin, Object maxDate, boolean includingMax) { minTime = ConstraintUtils.objectToTimeMillis(minDate); this.includingMin = includingMin; maxTime = ConstraintUtils.objectToTimeMillis(maxDate); this.includingMax = includingMax; if (minTime != null && maxTime != null && minTime > maxTime) { log.warn("lower bound (" + minDate + ") is greater than upper bound (" + maxDate + "). No dates could be valid."); } if ((minTime == null && minDate != null) || (maxTime == null && maxDate != null)) { log.warn("some bound was ignored due to invalid date format (supported format is " + ConstraintUtils.DATE_FORMAT + " (min = " + minDate + " - max = " + maxDate + ")"); } }
/** * For a fixed length, use min = max values. * <p> * Bounds could be any object having toString representating an integer. * </p> * * @param min Minimum length for the validated String, use a null value to get unbounded length. * @param max Maximum length for the validated String, use a null value to get unbounded length. */ public LengthConstraint(Object min, Object max) { this.min = ConstraintUtils.objectToPostiveLong(min); this.max = ConstraintUtils.objectToPostiveLong(max); }
@Override public boolean isNillable() { return ConstraintUtils.getConstraint(constraints, NotNullConstraint.class) == null; }
@Override public Set<Constraint> getConstraints() { Set<Constraint> constraints = new HashSet<Constraint>(); constraints.add(new TypeConstraint(this)); return constraints; }
/** * This method should be the only one to create {@link ConstraintViolation}. * * @since 7.1 */ private List<ConstraintViolation> validateSimpleTypeField(Schema schema, List<PathNode> path, Field field, Object value) { Type type = field.getType(); assert type.isSimpleType() || type.isListType(); // list type to manage ArrayProperty List<ConstraintViolation> violations = new ArrayList<>(); Set<Constraint> constraints; if (type.isListType()) { // ArrayProperty constraints = ((ListType) type).getFieldType().getConstraints(); } else { constraints = field.getConstraints(); } for (Constraint constraint : constraints) { if (!constraint.validate(value)) { ConstraintViolation violation = new ConstraintViolation(schema, path, constraint, value); violations.add(violation); } } return violations; }
/** * Here, value is : <br> * name = {@value #NAME} <br> * parameter = * <ul> * <li>{@value #PNAME_VALUES} : List[value1, value2, value3]</li> * </ul> */ @Override public Description getDescription() { Map<String, Serializable> params = new HashMap<>(); params.put(EnumConstraint.PNAME_VALUES, new ArrayList<>(possibleValues)); return new Description(EnumConstraint.NAME, params); }
@Override public boolean validate(Object object) { BigDecimal val = ConstraintUtils.objectToBigDecimal(object); if (val == null) { return true; } if (min != null) { int test = min.compareTo(val); if (test > 0) { return false; } if (!includingMin && test == 0) { return false; } } if (max != null) { int test = max.compareTo(val); if (test < 0) { return false; } if (!includingMax && test == 0) { return false; } } return true; }
@Override public boolean validate(Object object) { if (object == null) { return true; } Long timeValue = ConstraintUtils.objectToTimeMillis(object); if (timeValue == null) { return false; } if (minTime != null) { if (timeValue < minTime.longValue()) { return false; } if (!includingMin && timeValue == minTime.longValue()) { return false; } } if (maxTime != null) { if (timeValue > maxTime.longValue()) { return false; } if (!includingMax && timeValue == maxTime.longValue()) { return false; } } return true; }
/** * <p> * Here, value is : <br> * name = {@value #NAME} <br> * parameters = * <ul> * <li>{@value #PNAME_PATTERN} : [0-9]+</li> * </ul> * </p> */ @Override public Description getDescription() { Map<String, Serializable> params = new HashMap<String, Serializable>(); params.put(PNAME_PATTERN, pattern.pattern()); return new Description(PatternConstraint.NAME, params); }
/** * <p> * Here, value is : <br> * name = {@value #NAME} <br> * parameters = * <ul> * <li>{@value #PNAME_TYPE} : org.nuxeo.ecm.core.schema.types.primitives.IntegerType</li> * </ul> * </p> */ @Override public Description getDescription() { return new Description(type.getName(), new HashMap<String, Serializable>()); }
@Override public Description getDescription() { Map<String, Serializable> parameters = Collections.unmodifiableMap(resolver.getParameters()); return new Description(resolver.getName(), parameters); }