From 3a882522a02ddb387c73e0c24caea2823cb8ec40 Mon Sep 17 00:00:00 2001 From: Ben Fortuna Date: Tue, 23 Jun 2020 19:00:38 +1000 Subject: [PATCH] Ensure validators are serializable --- .../ical4j/model/component/Available.java | 10 ++-- .../ical4j/model/component/VAlarm.java | 5 +- .../ical4j/model/component/VAvailability.java | 8 +++- .../fortuna/ical4j/model/component/VToDo.java | 2 - .../ical4j/model/property/DateProperty.java | 46 ++++++++----------- .../ical4j/model/property/Trigger.java | 4 +- 6 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/fortuna/ical4j/model/component/Available.java b/src/main/java/net/fortuna/ical4j/model/component/Available.java index 2eddff206..a8037c9d1 100644 --- a/src/main/java/net/fortuna/ical4j/model/component/Available.java +++ b/src/main/java/net/fortuna/ical4j/model/component/Available.java @@ -39,7 +39,9 @@ import net.fortuna.ical4j.validate.ValidationRule; import net.fortuna.ical4j.validate.Validator; +import java.io.Serializable; import java.util.Optional; +import java.util.function.Predicate; import static net.fortuna.ical4j.model.Property.*; import static net.fortuna.ical4j.validate.ValidationRule.ValidationType.*; @@ -98,10 +100,10 @@ public class Available extends Component { new ValidationRule<>(One, DTSTART, DTSTAMP, UID), new ValidationRule<>(OneOrLess, CREATED, LAST_MODIFIED, RECURRENCE_ID, RRULE, SUMMARY), // can't have both DTEND and DURATION.. - new ValidationRule<>(One, p->!p.getProperties().getFirst(DURATION).isPresent(), DTEND), - new ValidationRule<>(None, p->p.getProperties().getFirst(DTEND).isPresent(), DURATION), - new ValidationRule<>(One, p->!p.getProperties().getFirst(DTEND).isPresent(), DURATION), - new ValidationRule<>(None, p->p.getProperties().getFirst(DURATION).isPresent(), DTEND) + new ValidationRule<>(None, + (Predicate & Serializable) p->p.getProperties().getFirst(DTEND).isPresent(), DURATION), + new ValidationRule<>(None, + (Predicate & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), DTEND) ); /** diff --git a/src/main/java/net/fortuna/ical4j/model/component/VAlarm.java b/src/main/java/net/fortuna/ical4j/model/component/VAlarm.java index 87a82cec6..c292c8138 100644 --- a/src/main/java/net/fortuna/ical4j/model/component/VAlarm.java +++ b/src/main/java/net/fortuna/ical4j/model/component/VAlarm.java @@ -41,11 +41,13 @@ import net.fortuna.ical4j.validate.ValidationRule; import net.fortuna.ical4j.validate.Validator; +import java.io.Serializable; import java.time.Instant; import java.time.temporal.TemporalAmount; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.function.Predicate; import static net.fortuna.ical4j.model.Property.*; import static net.fortuna.ical4j.validate.ValidationRule.ValidationType.*; @@ -217,7 +219,8 @@ public class VAlarm extends CalendarComponent { new ValidationRule<>(One, ACTION, TRIGGER), new ValidationRule<>(OneOrLess, DURATION, REPEAT), // DURATION and REPEAT must both be present or both absent - new ValidationRule<>(One, p->p.getProperties().getFirst(DURATION).isPresent(), REPEAT) + new ValidationRule<>(One, + (Predicate & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), REPEAT) ); /** diff --git a/src/main/java/net/fortuna/ical4j/model/component/VAvailability.java b/src/main/java/net/fortuna/ical4j/model/component/VAvailability.java index d588a33dd..8e44f8228 100644 --- a/src/main/java/net/fortuna/ical4j/model/component/VAvailability.java +++ b/src/main/java/net/fortuna/ical4j/model/component/VAvailability.java @@ -44,7 +44,9 @@ import net.fortuna.ical4j.validate.Validator; import org.jooq.lambda.Unchecked; +import java.io.Serializable; import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Collectors; import static net.fortuna.ical4j.model.Property.*; @@ -109,8 +111,10 @@ public class VAvailability extends CalendarComponent { new ValidationRule<>(One, DTSTART, DTSTAMP, UID), new ValidationRule<>(OneOrLess, BUSYTYPE, CREATED, LAST_MODIFIED, ORGANIZER, SEQUENCE, SUMMARY, URL), // can't have both DTEND and DURATION.. - new ValidationRule<>(None, p->p.getProperties().getFirst(DTEND).isPresent(), DURATION), - new ValidationRule<>(None, p->p.getProperties().getFirst(DURATION).isPresent(), DTEND) + new ValidationRule<>(None, + (Predicate & Serializable) p->p.getProperties().getFirst(DTEND).isPresent(), DURATION), + new ValidationRule<>(None, + (Predicate & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), DTEND) ); private ComponentList available; diff --git a/src/main/java/net/fortuna/ical4j/model/component/VToDo.java b/src/main/java/net/fortuna/ical4j/model/component/VToDo.java index a9e9aa130..6a6b33c55 100644 --- a/src/main/java/net/fortuna/ical4j/model/component/VToDo.java +++ b/src/main/java/net/fortuna/ical4j/model/component/VToDo.java @@ -172,9 +172,7 @@ public class VToDo extends CalendarComponent { LAST_MODIFIED, LOCATION, ORGANIZER, PERCENT_COMPLETE, PRIORITY, RECURRENCE_ID, SEQUENCE, STATUS, SUMMARY, UID, URL), // can't have both DUE and DURATION.. - new ValidationRule<>(One, p->!p.getProperties().getFirst(DURATION).isPresent(), DUE), new ValidationRule<>(None, p->p.getProperties().getFirst(DUE).isPresent(), DURATION), - new ValidationRule<>(One, p->!p.getProperties().getFirst(DUE).isPresent(), DURATION), new ValidationRule<>(None, p->p.getProperties().getFirst(DURATION).isPresent(), DUE) ); diff --git a/src/main/java/net/fortuna/ical4j/model/property/DateProperty.java b/src/main/java/net/fortuna/ical4j/model/property/DateProperty.java index 09c2cb583..9c7b76783 100644 --- a/src/main/java/net/fortuna/ical4j/model/property/DateProperty.java +++ b/src/main/java/net/fortuna/ical4j/model/property/DateProperty.java @@ -36,15 +36,22 @@ import net.fortuna.ical4j.model.parameter.Value; import net.fortuna.ical4j.util.CompatibilityHints; import net.fortuna.ical4j.util.Strings; -import net.fortuna.ical4j.validate.ParameterValidator; +import net.fortuna.ical4j.validate.PropertyValidator; import net.fortuna.ical4j.validate.ValidationException; +import net.fortuna.ical4j.validate.ValidationRule; +import net.fortuna.ical4j.validate.Validator; import org.slf4j.LoggerFactory; +import java.io.Serializable; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeParseException; import java.time.temporal.Temporal; import java.util.Optional; +import java.util.function.Predicate; + +import static net.fortuna.ical4j.model.Parameter.VALUE; +import static net.fortuna.ical4j.validate.ValidationRule.ValidationType.*; /** * $Id$ @@ -77,6 +84,13 @@ public abstract class DateProperty extends Property { private transient TimeZoneRegistry timeZoneRegistry; + private final Validator> validator = new PropertyValidator<>( + new ValidationRule<>(OneOrLess, VALUE), + new ValidationRule<>(One, (Predicate> & Serializable) p -> p.getDate() instanceof LocalDate, VALUE), + new ValidationRule<>(None, (Predicate> & Serializable) DateProperty::isUtc, TZID), + new ValidationRule<>(OneOrLess, (Predicate> & Serializable) p -> !p.isUtc(), TZID) + ); + /** * @param name the property name * @param parameters a list of initial parameters @@ -209,7 +223,7 @@ public final boolean isUtc() { * {@inheritDoc} */ public void validate() throws ValidationException { - + validator.validate(this); /* * ; the following are optional, ; but MUST NOT occur more than once (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / * (";" tzidparam) / @@ -219,41 +233,17 @@ public void validate() throws ValidationException { * ; the following is optional, ; and MAY occur more than once (";" xparam) */ - ParameterValidator.assertOneOrLess(Parameter.VALUE, getParameters().getAll()); - - if (isUtc()) { - ParameterValidator.assertNone(Parameter.TZID, getParameters().getAll()); - } else { - ParameterValidator.assertOneOrLess(Parameter.TZID, getParameters().getAll()); - } - - final Optional value = getParameters().getFirst(Parameter.VALUE); + final Optional value = getParameters().getFirst(VALUE); if (date != null) { if (date.getTemporal() instanceof LocalDate) { - if (!value.isPresent()) { - throw new ValidationException("VALUE parameter [" + Value.DATE + "] must be specified for DATE instance"); - } else if (!Value.DATE.equals(value.get())) { + if (value.isPresent() && !Value.DATE.equals(value.get())) { throw new ValidationException("VALUE parameter [" + value.get() + "] is invalid for DATE instance"); } } else { if (value.isPresent() && !Value.DATE_TIME.equals(value.get())) { throw new ValidationException("VALUE parameter [" + value.get() + "] is invalid for DATE-TIME instance"); } - - /* We can allow change to TZID as the date will be resolved with zone id at output (see getValue()) - if (date.getTemporal() instanceof ZonedDateTime) { - ZonedDateTime dateTime = (ZonedDateTime) date.getTemporal(); - - // ensure tzid matches date-time timezone.. - final Optional tzId = getParameter(Parameter.TZID); - if (!tzId.isPresent() || !tzId.get().toZoneId(timeZoneRegistry).equals(dateTime.getZone())) { - throw new ValidationException("TZID parameter [" + tzId.get() + "] does not match the timezone [" - + dateTime.getZone() + "]"); - } - } - - */ } } } diff --git a/src/main/java/net/fortuna/ical4j/model/property/Trigger.java b/src/main/java/net/fortuna/ical4j/model/property/Trigger.java index 1e7d2a6c4..6c6c70d3a 100644 --- a/src/main/java/net/fortuna/ical4j/model/property/Trigger.java +++ b/src/main/java/net/fortuna/ical4j/model/property/Trigger.java @@ -39,10 +39,12 @@ import net.fortuna.ical4j.validate.Validator; import org.slf4j.LoggerFactory; +import java.io.Serializable; import java.time.Instant; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAmount; import java.util.Optional; +import java.util.function.Predicate; import static net.fortuna.ical4j.model.Parameter.RELATED; import static net.fortuna.ical4j.model.Parameter.VALUE; @@ -159,7 +161,7 @@ public class Trigger extends DateProperty { private Validator validator = new PropertyValidator<>( new ValidationRule<>(OneOrLess, VALUE), - new ValidationRule<>(None, Trigger::isAbsolute, RELATED) + new ValidationRule<>(None, (Predicate & Serializable) Trigger::isAbsolute, RELATED) ); /**