Skip to content

Commit

Permalink
Ensure validators are serializable
Browse files Browse the repository at this point in the history
  • Loading branch information
benfortuna committed Jun 23, 2020
1 parent 82fc509 commit 3a88252
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 38 deletions.
10 changes: 6 additions & 4 deletions src/main/java/net/fortuna/ical4j/model/component/Available.java
Expand Up @@ -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.*;
Expand Down Expand Up @@ -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<Available> & Serializable) p->p.getProperties().getFirst(DTEND).isPresent(), DURATION),
new ValidationRule<>(None,
(Predicate<Available> & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), DTEND)
);

/**
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/net/fortuna/ical4j/model/component/VAlarm.java
Expand Up @@ -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.*;
Expand Down Expand Up @@ -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<VAlarm> & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), REPEAT)
);

/**
Expand Down
Expand Up @@ -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.*;
Expand Down Expand Up @@ -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<VAvailability> & Serializable) p->p.getProperties().getFirst(DTEND).isPresent(), DURATION),
new ValidationRule<>(None,
(Predicate<VAvailability> & Serializable) p->p.getProperties().getFirst(DURATION).isPresent(), DTEND)
);

private ComponentList<Available> available;
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/net/fortuna/ical4j/model/component/VToDo.java
Expand Up @@ -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)
);

Expand Down
46 changes: 18 additions & 28 deletions src/main/java/net/fortuna/ical4j/model/property/DateProperty.java
Expand Up @@ -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$
Expand Down Expand Up @@ -77,6 +84,13 @@ public abstract class DateProperty<T extends Temporal> extends Property {

private transient TimeZoneRegistry timeZoneRegistry;

private final Validator<DateProperty<T>> validator = new PropertyValidator<>(
new ValidationRule<>(OneOrLess, VALUE),
new ValidationRule<>(One, (Predicate<DateProperty<T>> & Serializable) p -> p.getDate() instanceof LocalDate, VALUE),
new ValidationRule<>(None, (Predicate<DateProperty<T>> & Serializable) DateProperty::isUtc, TZID),
new ValidationRule<>(OneOrLess, (Predicate<DateProperty<T>> & Serializable) p -> !p.isUtc(), TZID)
);

/**
* @param name the property name
* @param parameters a list of initial parameters
Expand Down Expand Up @@ -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) /
Expand All @@ -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> value = getParameters().getFirst(Parameter.VALUE);
final Optional<Value> 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> 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() + "]");
}
}
*/
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/net/fortuna/ical4j/model/property/Trigger.java
Expand Up @@ -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;
Expand Down Expand Up @@ -159,7 +161,7 @@ public class Trigger extends DateProperty<Instant> {

private Validator<Trigger> validator = new PropertyValidator<>(
new ValidationRule<>(OneOrLess, VALUE),
new ValidationRule<>(None, Trigger::isAbsolute, RELATED)
new ValidationRule<>(None, (Predicate<Trigger> & Serializable) Trigger::isAbsolute, RELATED)
);

/**
Expand Down

0 comments on commit 3a88252

Please sign in to comment.