Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package TVShowTimelineMaker.timeConstraints; import TVShowTimelineMaker.timeConstraints.core.AbstractTwoEventTimeConstraint; import TVShowTimelineMaker.timeConstraints.core.TimeConstraintImp; import TVShowTimelineMaker.timeConstraints.interfaces.TwoOnceDayEventTimeConstraint; import TVShowTimelineMaker.timeline.DayEvent; import TVShowTimelineMaker.timeline.Event; import TVShowTimelineMaker.timeline.EventImp; import TVShowTimelineMaker.timeline.OnceDayEvent; import TVShowTimelineMaker.timeline.OnceEvent; import TVShowTimelineMaker.timeline.OncePeriodEvent; import TVShowTimelineMaker.timeline.PeriodEvent; import TVShowTimelineMaker.timeline.PlacementEvent.Placement; import TVShowTimelineMaker.util.MyLittePonyMaps; import TVShowTimelineMaker.util.XML.XMLWriter; import TVShowTimelineMaker.util.XML.XMLWriterImp; import java.util.Iterator; import java.util.NavigableSet; import java.util.logging.Logger; import org.jdom2.Element; import org.joda.time.DateTime; import org.joda.time.ReadablePeriod; public class Relation<T extends Placement<DateTime>, S extends Placement<DateTime>> extends AbstractTwoEventTimeConstraint<T, S> { private static final long serialVersionUID = 9L; private static final Logger LOG = Logger.getLogger(Relation.class.getName()); @com.civprod.dynamicClassLoading.ClassInitalizer public static final void init() { MyLittePonyMaps.putConstraint("Relation", Relation.class); } private static RelationKind readKindElement(Element kindElement) { RelationKind kind; String kindText = kindElement.getTextNormalize(); if (kindText.contains(RelationKind.SAME_DAY_OF_YEAR.name())) { kind = RelationKind.SAME_DAY_OF_YEAR; } else { kind = RelationKind.valueOf(kindElement.getTextNormalize()); } return kind; } private static ReadablePeriod readTimeElement(Element TimeElement) { ReadablePeriod time; if (TimeElement != null) { XMLWriter<ReadablePeriod> ReadablePeriodWriter = XMLWriterImp.getXMLWriter(ReadablePeriod.class); time = ReadablePeriodWriter.readElements(TimeElement.getChildren().get(0)); } else { time = null; } return time; } private final OnceEvent<T> firstEpisode; private final OnceEvent<S> secondEpisode; private final Event rConstrainedEvents[]; private final RelationKind kind; private final org.joda.time.ReadablePeriod time; protected final SameTimeOfYearConstraint mSameTimeOfYearConstraint; public Relation(OnceEvent<T> inFirstEpisode, OnceEvent<S> inSecondEpisode, RelationKind inKind) { this(inFirstEpisode, inSecondEpisode, inKind, null); } public Relation(OnceEvent<T> inFirstEpisode, OnceEvent<S> inSecondEpisode, RelationKind inKind, ReadablePeriod inPeriod) { this(false, inFirstEpisode, inSecondEpisode, inKind, inPeriod); } public Relation(boolean isSynthetic, OnceEvent<T> inFirstEpisode, OnceEvent<S> inSecondEpisode, RelationKind inKind) { this(isSynthetic, inFirstEpisode, inSecondEpisode, inKind, null); } public Relation(boolean isSynthetic, OnceEvent<T> inFirstEpisode, OnceEvent<S> inSecondEpisode, RelationKind inKind, ReadablePeriod inPeriod) { super(isSynthetic); this.firstEpisode = inFirstEpisode; this.secondEpisode = inSecondEpisode; this.kind = inKind; this.time = inPeriod; this.mSameTimeOfYearConstraint = (this.kind == RelationKind.SAME_DAY_OF_YEAR) ? new SameTimeOfYearConstraint( (DayEvent<DateTime, ? extends DayEvent.DayPlacement<DateTime>>) this.firstEpisode, (DayEvent<DateTime, ? extends DayEvent.DayPlacement<DateTime>>) this.secondEpisode) : null; this.rConstrainedEvents = new OnceEvent[2]; this.rConstrainedEvents[0] = this.firstEpisode; this.rConstrainedEvents[1] = this.secondEpisode; } protected Relation(Element root) { this(root, (OnceEvent<T>) EventImp.EventIDXMLWriter.instance.readElements(root.getChild("firstEventByID")), (OnceEvent<S>) EventImp.EventIDXMLWriter.instance.readElements(root.getChild("secondEventByID")), readKindElement(root.getChild("kind")), readTimeElement(root.getChild("time"))); } protected Relation(Element root, OnceEvent<T> inFirstEpisode, OnceEvent<S> inSecondEpisode, RelationKind inKind, ReadablePeriod inPeriod) { super(root); this.firstEpisode = inFirstEpisode; this.secondEpisode = inSecondEpisode; this.kind = inKind; this.time = inPeriod; this.mSameTimeOfYearConstraint = (this.kind == RelationKind.SAME_DAY_OF_YEAR) ? new SameTimeOfYearConstraint( (DayEvent<DateTime, ? extends DayEvent.DayPlacement<DateTime>>) this.firstEpisode, (DayEvent<DateTime, ? extends DayEvent.DayPlacement<DateTime>>) this.secondEpisode) : null; this.rConstrainedEvents = new OnceEvent[2]; this.rConstrainedEvents[0] = this.firstEpisode; this.rConstrainedEvents[1] = this.secondEpisode; } public boolean isValid() { if ((this.kind == RelationKind.LESS_THEN_BEFORE) || (this.kind == RelationKind.MORE_THEN_BEFORE)) { return this.time != null; } return true; } @Override public boolean inBeta() { return false; } @Override public boolean isStrictlyBefore() { return !(this.kind.equals(RelationKind.SAME_TIME_AS) || this.kind.equals(RelationKind.SAME_DAY_OF_YEAR)); } /** * @return the firstEpisode */ @Override public Event getFirstEvent() { return this.firstEpisode; } /** * @return the secondEpisode */ @Override public Event getSecondEvent() { return this.secondEpisode; } /** * @return the kind */ public RelationKind getKind() { return this.kind; } /** * @return the time */ public org.joda.time.ReadablePeriod getTime() { return this.time; } @Override public boolean isStrict() { if ((this.kind == RelationKind.IMMEDIATELY_BEFORE) || (this.kind == RelationKind.BEFORE)) { return false; } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { return true; } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { return true; } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { return true; } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { return this.mSameTimeOfYearConstraint.isStrict(); } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { return false; } else { return false; } } @Override public boolean complexApplyConstraint() { boolean changed = this.applyConstraint(); if ((!this.firstEpisode.isMarkedForComplexEval()) && this.secondEpisode.isMarkedForComplexEval()) { if ((this.kind == RelationKind.FIXED_TIME_BEFORE) || (this.kind == RelationKind.SAME_DAY_OF_YEAR) || (this.kind == RelationKind.LESS_THEN_BEFORE) || (this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { this.firstEpisode.setUpForComplexEval(); } } if (this.firstEpisode.isMarkedForComplexEval() && (!this.secondEpisode.isMarkedForComplexEval())) { if ((this.kind == RelationKind.FIXED_TIME_BEFORE) || (this.kind == RelationKind.SAME_DAY_OF_YEAR) || (this.kind == RelationKind.LESS_THEN_BEFORE) || (this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { this.secondEpisode.setUpForComplexEval(); } } if (this.firstEpisode.isMarkedForComplexEval() && this.secondEpisode.isMarkedForComplexEval()) { NavigableSet<DateTime> firstEpisodeStartDates; NavigableSet<DateTime> firstEpisodeEndDates; NavigableSet<DateTime> secondEpisodeStartDates; NavigableSet<DateTime> secondEpisodeEndDates; if (this.firstEpisode instanceof OnceDayEvent) { OnceDayEvent firstEpisodeDayEvent = (OnceDayEvent) this.firstEpisode; firstEpisodeStartDates = firstEpisodeDayEvent.getPossibleDays(); firstEpisodeEndDates = firstEpisodeDayEvent.getPossibleDays(); } else if (this.firstEpisode instanceof OncePeriodEvent) { OncePeriodEvent firstEpisodePeriodEvent = (OncePeriodEvent) this.firstEpisode; firstEpisodeStartDates = firstEpisodePeriodEvent.getStartPossibleDays(); firstEpisodeEndDates = firstEpisodePeriodEvent.getEndPossibleDays(); } else { throw new UnsupportedOperationException( this.firstEpisode.getClass().getCanonicalName() + "Not supported yet"); } if (this.secondEpisode instanceof OnceDayEvent) { OnceDayEvent secondEpisodeDayEvent = (OnceDayEvent) this.secondEpisode; secondEpisodeStartDates = secondEpisodeDayEvent.getPossibleDays(); secondEpisodeEndDates = secondEpisodeDayEvent.getPossibleDays(); } else if (this.secondEpisode instanceof OncePeriodEvent) { OncePeriodEvent secondEpisodePeriodEvent = (OncePeriodEvent) this.secondEpisode; secondEpisodeStartDates = secondEpisodePeriodEvent.getStartPossibleDays(); secondEpisodeEndDates = secondEpisodePeriodEvent.getEndPossibleDays(); } else { throw new UnsupportedOperationException( this.firstEpisode.getClass().getCanonicalName() + "Not supported yet"); } Iterator<DateTime> firstEpisodeStartDatesIterator = firstEpisodeStartDates.iterator(); Iterator<DateTime> secondEpisodeStartDatesIterator = secondEpisodeStartDates.iterator(); DateTime curFirstEpisodeStartDate = firstEpisodeStartDatesIterator.next(); DateTime curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); Iterator<DateTime> firstEpisodeEndDatesIterator = firstEpisodeEndDates.iterator(); Iterator<DateTime> secondEpisodeEndDatesIterator = secondEpisodeEndDates.iterator(); DateTime curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); DateTime curSecondEpisodeEndDate = secondEpisodeEndDatesIterator.next(); boolean cont = true; if (this.kind == RelationKind.IMMEDIATELY_BEFORE) { DateTime startOfLastDay = secondEpisodeStartDates.last().withHourOfDay(1); /*while (indexInToFirstEpisodeDatesDates < firstEpisodeDates.size()) { if (firstEpisodeDates.get(indexInToFirstEpisodeDatesDates).isAfter(startOfLastDay)) { firstEpisodeDates.remove(indexInToFirstEpisodeDatesDates); changed = true; } else { indexInToFirstEpisodeDatesDates++; } }*/ while (!firstEpisodeEndDates.isEmpty()) { if (firstEpisodeEndDates.last().isAfter(startOfLastDay)) { firstEpisodeEndDates.pollLast(); changed = true; } else { break; } } DateTime endOfFirstPossibleDay = firstEpisodeEndDates.first().withHourOfDay(23); while (cont) { if (endOfFirstPossibleDay.isAfter(curSecondEpisodeStartDate)) { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } changed = true; } else { //indexInToSecondEpisodeDatesDates++; break; } } } else if (this.kind == RelationKind.BEFORE) { DateTime startOfLastDay = secondEpisodeStartDates.last().withHourOfDay(1); /*while (indexInToFirstEpisodeDatesDates < firstEpisodeDates.size()) { if (firstEpisodeDates.get(indexInToFirstEpisodeDatesDates).isAfter(startOfLastDay)) { firstEpisodeDates.remove(indexInToFirstEpisodeDatesDates); changed = true; } else { indexInToFirstEpisodeDatesDates++; } }*/ while (!firstEpisodeEndDates.isEmpty()) { if (firstEpisodeEndDates.last().isAfter(startOfLastDay)) { firstEpisodeEndDates.pollLast(); changed = true; } else { break; } } DateTime endOfFirstPossibleDay = firstEpisodeEndDates.first().withHourOfDay(23); while (cont) { if (endOfFirstPossibleDay.isAfter(curSecondEpisodeStartDate)) { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } changed = true; } else { //indexInToSecondEpisodeDatesDates++; break; } } } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { //while (indexInToFirstEpisodeDatesDates < firstEpisodeEndDates.size()) { while (cont) { //DateTime later = firstEpisodeEndDates.get(indexInToFirstEpisodeDatesDates).plus(time); DateTime later = curFirstEpisodeEndDate.plus(this.time); if (secondEpisodeStartDates.contains(later)) { if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); } else { break; } } else { firstEpisodeEndDatesIterator.remove(); if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); } else { cont = false; } changed = true; } } while (cont) { DateTime earlier = curSecondEpisodeStartDate.minus(this.time); if (firstEpisodeEndDates.contains(earlier)) { if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { break; } } else { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } changed = true; } } } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime startOfDay = curSecondEpisodeStartDate.withHourOfDay(1); DateTime tempEarliestPossibleDate = curSecondEpisodeStartDate.minus(this.time).withHourOfDay(1); while (cont) { if (curFirstEpisodeEndDate.isBefore(tempEarliestPossibleDate)) { firstEpisodeEndDatesIterator.remove(); if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); } else { cont = false; } changed = true; } else if (curFirstEpisodeEndDate.isAfter(startOfDay)) { //if (indexInToSecondEpisodeDatesDates < secondEpisodeStartDates.size()) { if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); startOfDay = curSecondEpisodeStartDate.withHourOfDay(1); tempEarliestPossibleDate = curSecondEpisodeStartDate.minus(this.time).withHourOfDay(1); } else { firstEpisodeEndDatesIterator.remove(); if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); } else { cont = false; } changed = true; } } else { if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); } else { cont = false; } } } firstEpisodeStartDatesIterator = firstEpisodeStartDates.iterator(); secondEpisodeStartDatesIterator = secondEpisodeStartDates.iterator(); curFirstEpisodeStartDate = firstEpisodeStartDatesIterator.next(); curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); firstEpisodeEndDatesIterator = firstEpisodeEndDates.iterator(); secondEpisodeEndDatesIterator = secondEpisodeEndDates.iterator(); curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); curSecondEpisodeEndDate = secondEpisodeEndDatesIterator.next(); cont = true; DateTime endOfDay = curFirstEpisodeEndDate.withHourOfDay(23); DateTime tempLatestPossibleDate = curFirstEpisodeEndDate.plus(this.time).withHourOfDay(23); while (cont) { if (curSecondEpisodeStartDate.isBefore(endOfDay)) { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } changed = true; } else if (curSecondEpisodeStartDate.isAfter(tempLatestPossibleDate)) { //indexInToFirstEpisodeDatesDates++; //if (indexInToFirstEpisodeDatesDates < firstEpisodeEndDates.size()) { if (firstEpisodeEndDatesIterator.hasNext()) { curFirstEpisodeEndDate = firstEpisodeEndDatesIterator.next(); endOfDay = curFirstEpisodeEndDate.withHourOfDay(23); tempLatestPossibleDate = curFirstEpisodeEndDate.plus(this.time).withHourOfDay(23); } else { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } changed = true; } } else { if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = false; } } } } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { changed |= this.mSameTimeOfYearConstraint.complexApplyConstraint(); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { Iterator<DateTime> iterator = firstEpisodeStartDates.iterator(); while (iterator.hasNext()) { DateTime next = iterator.next(); if (!secondEpisodeStartDates.contains(next)) { iterator.remove(); changed = true; } } iterator = secondEpisodeStartDates.iterator(); while (iterator.hasNext()) { DateTime next = iterator.next(); if (!firstEpisodeStartDates.contains(next)) { iterator.remove(); changed = true; } } iterator = firstEpisodeEndDates.iterator(); while (iterator.hasNext()) { DateTime next = iterator.next(); if (!secondEpisodeEndDates.contains(next)) { iterator.remove(); changed = true; } } iterator = secondEpisodeEndDates.iterator(); while (iterator.hasNext()) { DateTime next = iterator.next(); if (!firstEpisodeEndDates.contains(next)) { iterator.remove(); changed = true; } } } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime tempEarliestPossibleDateForSecondEpisode = firstEpisodeEndDates.first().plus(this.time) .withHourOfDay(1); DateTime tempLatestPossibleDateForFirstEpisode = secondEpisodeStartDates.last().minus(this.time) .withHourOfDay(23); /*while (indexInToFirstEpisodeDatesDates < firstEpisodeDates.size()) { if (firstEpisodeDates.get(indexInToFirstEpisodeDatesDates).isAfter(tempLatestPossibleDateForFirstEpisode)) { firstEpisodeDates.remove(indexInToFirstEpisodeDatesDates); changed = true; } else { indexInToFirstEpisodeDatesDates++; } }*/ while (!firstEpisodeEndDates.isEmpty()) { if (firstEpisodeEndDates.last().isAfter(tempLatestPossibleDateForFirstEpisode)) { firstEpisodeEndDates.pollLast(); changed = true; } else { break; } } while (cont) { if (tempEarliestPossibleDateForSecondEpisode.isAfter(curSecondEpisodeStartDate)) { secondEpisodeStartDatesIterator.remove(); if (secondEpisodeStartDatesIterator.hasNext()) { curSecondEpisodeStartDate = secondEpisodeStartDatesIterator.next(); } else { cont = true; } changed = true; } else { //indexInToSecondEpisodeDatesDates++; break; } } } } return changed; } @Override public boolean applyConstraint() { boolean changed = false; DateTime dayAfterFirstEpisode = this.firstEpisode.getEarliestPossibleStartTime().plusDays(1) .withHourOfDay(1); DateTime dayBeforeSecondEpisode = this.secondEpisode.getLatestPossibleEndTime().minusDays(1) .withHourOfDay(23); if (this.kind == RelationKind.IMMEDIATELY_BEFORE) { changed = this.secondEpisode.setAfter(dayAfterFirstEpisode) || changed; changed = this.firstEpisode.setBefore(dayBeforeSecondEpisode) || changed; } else if (this.kind == RelationKind.BEFORE) { changed = this.secondEpisode.setAfter(dayAfterFirstEpisode) || changed; changed = this.firstEpisode.setBefore(dayBeforeSecondEpisode) || changed; } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { DateTime tempEarliestPossibleDateForFirstEpisode = this.secondEpisode.getEarliestPossibleStartTime() .minus(this.time).withHourOfDay(1); DateTime tempEarliestPossibleDateForSecondEpisode = this.firstEpisode.getEarliestPossibleStartTime() .plus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForFirstEpisode = this.secondEpisode.getLatestPossibleEndTime() .minus(this.time).withHourOfDay(23); DateTime tempLatestPossibleDateForSecondEpisode = this.firstEpisode.getLatestPossibleEndTime() .plus(this.time).withHourOfDay(23); changed = this.secondEpisode.setAfter(tempEarliestPossibleDateForSecondEpisode) || changed; changed = this.firstEpisode.setAfter(tempEarliestPossibleDateForFirstEpisode) || changed; changed = this.firstEpisode.setBefore(tempLatestPossibleDateForFirstEpisode) || changed; changed = this.secondEpisode.setBefore(tempLatestPossibleDateForSecondEpisode) || changed; } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime tempEarliestPossibleDateForFirstEpisode = this.secondEpisode.getEarliestPossibleStartTime() .minus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForSecondEpisode = this.firstEpisode.getLatestPossibleEndTime() .plus(this.time).withHourOfDay(23); changed = this.secondEpisode.setAfter(dayAfterFirstEpisode) || changed; changed = this.firstEpisode.setBefore(dayBeforeSecondEpisode) || changed; changed = this.firstEpisode.setAfter(tempEarliestPossibleDateForFirstEpisode) || changed; changed = this.secondEpisode.setBefore(tempLatestPossibleDateForSecondEpisode) || changed; } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { changed |= this.mSameTimeOfYearConstraint.applyConstraint(); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { if (this.firstEpisode.getEarliestPossibleStartTime().withHourOfDay(1) .isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { changed = this.secondEpisode.setAfter(this.firstEpisode.getEarliestPossibleStartTime()) || changed; } if (this.secondEpisode.getEarliestPossibleStartTime().withHourOfDay(1) .isAfter(this.firstEpisode.getEarliestPossibleStartTime())) { changed = this.firstEpisode.setAfter(this.secondEpisode.getEarliestPossibleStartTime()) || changed; } if (this.firstEpisode.getLatestPossibleEndTime() .isAfter(this.secondEpisode.getLatestPossibleEndTime().withHourOfDay(23))) { changed = this.firstEpisode.setBefore(this.secondEpisode.getLatestPossibleEndTime()) || changed; } if (this.secondEpisode.getLatestPossibleEndTime() .isAfter(this.firstEpisode.getLatestPossibleEndTime().withHourOfDay(23))) { changed = this.secondEpisode.setBefore(this.firstEpisode.getLatestPossibleEndTime()) || changed; } } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime tempEarliestPossibleDateForSecondEpisode = this.firstEpisode.getEarliestPossibleStartTime() .plus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForFirstEpisode = this.secondEpisode.getLatestPossibleEndTime() .minus(this.time).withHourOfDay(23); if (dayAfterFirstEpisode.isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { changed = this.secondEpisode.setAfter(dayAfterFirstEpisode) || changed; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(dayBeforeSecondEpisode)) { changed = this.firstEpisode.setBefore(dayBeforeSecondEpisode) || changed; } if (tempEarliestPossibleDateForSecondEpisode .isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { changed = this.secondEpisode.setAfter(tempEarliestPossibleDateForSecondEpisode) || changed; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(tempLatestPossibleDateForFirstEpisode)) { changed = this.firstEpisode.setBefore(tempLatestPossibleDateForFirstEpisode) || changed; } } return changed; } @Override public Event[] getConstrainedEvents() { return this.rConstrainedEvents; } @Override public boolean ConstraintSatisfied() { boolean satisfied = true; DateTime dayAfterFirstEpisode = this.firstEpisode.getEarliestPossibleStartTime().plusDays(1) .withHourOfDay(1); DateTime dayBeforeSecondEpisode = this.secondEpisode.getLatestPossibleEndTime().minusDays(1) .withHourOfDay(23); if (this.kind == RelationKind.IMMEDIATELY_BEFORE) { if (dayAfterFirstEpisode.isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(dayBeforeSecondEpisode)) { satisfied = false; } } else if (this.kind == RelationKind.BEFORE) { if (dayAfterFirstEpisode.isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(dayBeforeSecondEpisode)) { satisfied = false; } } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { DateTime tempEarliestPossibleDateForFirstEpisode = this.secondEpisode.getEarliestPossibleStartTime() .minus(this.time).withHourOfDay(1); DateTime tempEarliestPossibleDateForSecondEpisode = this.firstEpisode.getEarliestPossibleStartTime() .plus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForFirstEpisode = this.secondEpisode.getLatestPossibleEndTime() .minus(this.time).withHourOfDay(23); DateTime tempLatestPossibleDateForSecondEpisode = this.firstEpisode.getLatestPossibleEndTime() .plus(this.time).withHourOfDay(23); if (tempEarliestPossibleDateForSecondEpisode .isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (tempEarliestPossibleDateForFirstEpisode.isAfter(this.firstEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(tempLatestPossibleDateForFirstEpisode)) { satisfied = false; } if (this.secondEpisode.getLatestPossibleEndTime().isAfter(tempLatestPossibleDateForSecondEpisode)) { satisfied = false; } } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime tempEarliestPossibleDateForFirstEpisode = this.secondEpisode.getEarliestPossibleStartTime() .minus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForSecondEpisode = this.firstEpisode.getLatestPossibleEndTime() .plus(this.time).withHourOfDay(23); if (dayAfterFirstEpisode.isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(dayBeforeSecondEpisode)) { satisfied = false; } if (tempEarliestPossibleDateForFirstEpisode.isAfter(this.firstEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.secondEpisode.getLatestPossibleEndTime().isAfter(tempLatestPossibleDateForSecondEpisode)) { satisfied = false; } } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { satisfied &= this.mSameTimeOfYearConstraint.ConstraintSatisfied(); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { if (this.firstEpisode.getEarliestPossibleStartTime().withHourOfDay(1) .isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.secondEpisode.getEarliestPossibleStartTime().withHourOfDay(1) .isAfter(this.firstEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime() .isAfter(this.secondEpisode.getLatestPossibleEndTime().withHourOfDay(23))) { satisfied = false; } if (this.secondEpisode.getLatestPossibleEndTime() .isAfter(this.firstEpisode.getLatestPossibleEndTime().withHourOfDay(23))) { satisfied = false; } } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime tempEarliestPossibleDateForSecondEpisode = this.firstEpisode.getEarliestPossibleStartTime() .plus(this.time).withHourOfDay(1); DateTime tempLatestPossibleDateForFirstEpisode = this.secondEpisode.getLatestPossibleEndTime() .minus(this.time).withHourOfDay(23); if (dayAfterFirstEpisode.isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(dayBeforeSecondEpisode)) { satisfied = false; } if (tempEarliestPossibleDateForSecondEpisode .isAfter(this.secondEpisode.getEarliestPossibleStartTime())) { satisfied = false; } if (this.firstEpisode.getLatestPossibleEndTime().isAfter(tempLatestPossibleDateForFirstEpisode)) { satisfied = false; } } return satisfied; } @Override public String toString() { String rString; if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { rString = this.mSameTimeOfYearConstraint.toString(); } else { rString = this.firstEpisode.toString(); if (this.kind == RelationKind.FIXED_TIME_BEFORE) { rString = rString + " is exactly " + this.time.toString() + " before "; } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { rString = rString + " within " + this.time.toString() + " of "; } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { rString = rString + " more than " + this.time.toString() + " before "; } else { rString = rString + " " + this.kind.toString() + " "; } rString += this.secondEpisode.toString(); } return rString; } public boolean consistentWithConstraint(DateTime inFirstDay, DateTime inSecondDay) { if ((this.kind == RelationKind.IMMEDIATELY_BEFORE) || (this.kind == RelationKind.BEFORE)) { return inFirstDay.isBefore(inSecondDay.withHourOfDay(1)); } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { return inFirstDay.plus(this.time).equals(inSecondDay); } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime tempEarliestPossibleDate = inSecondDay.minus(this.time).withHourOfDay(1); return inFirstDay.isAfter(tempEarliestPossibleDate) && inFirstDay.isBefore(inSecondDay.withHourOfDay(1)); } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { return (inFirstDay.getMonthOfYear() == inSecondDay.getMonthOfYear()) && (inFirstDay.getDayOfMonth() == inSecondDay.getDayOfMonth()); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { return this.mSameTimeOfYearConstraint.consistentWithConstraint(inFirstDay, inSecondDay); } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime earyer = inSecondDay.minus(this.time).withHourOfDay(1); return inFirstDay.isBefore(earyer); } else { return true; } } @Override public boolean consistentWithConstraint(T inFirstPlacement, S inSecondPlacement) { DateTime inFirstStartTime; DateTime inFirstEndTime; DateTime inSecondStartTime; DateTime inSecondEndTime; if (this.firstEpisode instanceof OnceDayEvent) { OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inFirstPlacement; inFirstStartTime = curOnceDayEventPlacement.day; inFirstEndTime = curOnceDayEventPlacement.day; } else { OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inFirstPlacement; inFirstStartTime = curOncePeriodEventPlacement.startDay; inFirstEndTime = curOncePeriodEventPlacement.endDay; } if (this.secondEpisode instanceof OnceDayEvent) { OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inSecondPlacement; inSecondStartTime = curOnceDayEventPlacement.day; inSecondEndTime = curOnceDayEventPlacement.day; } else { OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inSecondPlacement; inSecondStartTime = curOncePeriodEventPlacement.startDay; inSecondEndTime = curOncePeriodEventPlacement.endDay; } if ((this.kind == RelationKind.IMMEDIATELY_BEFORE) || (this.kind == RelationKind.BEFORE)) { return inFirstEndTime.isBefore(inSecondStartTime.withHourOfDay(1)); } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { return inFirstEndTime.plus(this.time).equals(inSecondStartTime); } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime tempEarliestPossibleDate = inSecondStartTime.minus(this.time).withHourOfDay(1); return inFirstEndTime.isAfter(tempEarliestPossibleDate) && inFirstEndTime.isBefore(inSecondStartTime.withHourOfDay(1)); } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { return this.mSameTimeOfYearConstraint.consistentWithConstraint(inFirstPlacement, inSecondPlacement); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { return inFirstStartTime.equals(inSecondStartTime) && inFirstEndTime.equals(inSecondEndTime); } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime earyer = inSecondStartTime.minus(this.time).withHourOfDay(1); return inFirstEndTime.isBefore(earyer); } else { return true; } } @Override public Event[] increaseWhat(Placement<?> inValues[]) { DateTime inFirstStartTime; DateTime inFirstEndTime; DateTime inSecondStartTime; DateTime inSecondEndTime; if (this.firstEpisode instanceof OnceDayEvent) { OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[0]; inFirstStartTime = curOnceDayEventPlacement.day; inFirstEndTime = curOnceDayEventPlacement.day; } else { return new Event[] { this.firstEpisode, this.secondEpisode }; } if (this.secondEpisode instanceof OnceDayEvent) { OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[1]; inSecondStartTime = curOnceDayEventPlacement.day; inSecondEndTime = curOnceDayEventPlacement.day; } else { return new Event[] { this.firstEpisode, this.secondEpisode }; } if ((this.kind == RelationKind.IMMEDIATELY_BEFORE) || (this.kind == RelationKind.BEFORE)) { if (!inFirstEndTime.isBefore(inSecondStartTime.withHourOfDay(1))) { return new Event[] { this.secondEpisode }; } } else if (this.kind == RelationKind.FIXED_TIME_BEFORE) { //inFirstEndTime.plus(this.time).equals(inSecondStartTime); DateTime later = inFirstEndTime.plus(this.time); if (later.isBefore(inSecondStartTime)) { return new Event[] { this.firstEpisode }; } else if (later.isAfter(inSecondStartTime)) { return new Event[] { this.secondEpisode }; } } else if (this.kind == RelationKind.LESS_THEN_BEFORE) { DateTime tempEarliestPossibleDate = inSecondStartTime.minus(this.time).withHourOfDay(1); if (!inFirstEndTime.isAfter(tempEarliestPossibleDate)) { return new Event[] { this.firstEpisode }; } if (!inFirstEndTime.isBefore(inSecondStartTime.withHourOfDay(1))) { return new Event[] { this.secondEpisode }; } } else if (this.kind == RelationKind.SAME_DAY_OF_YEAR) { return this.mSameTimeOfYearConstraint.increaseWhat(inValues); } else if ((this.kind == RelationKind.SAME_TIME_AS) || (this.kind == RelationKind.BEFORE_SAME_DAY)) { //inFirstStartTime.equals(inSecondStartTime) && inFirstEndTime.equals(inSecondEndTime); if (inFirstStartTime.isBefore(inSecondStartTime) || inFirstEndTime.isBefore(inSecondEndTime)) { return new Event[] { this.firstEpisode }; } else if (inFirstStartTime.isAfter(inSecondStartTime) || inFirstEndTime.isAfter(inSecondEndTime)) { return new Event[] { this.secondEpisode }; } } else if (this.kind == RelationKind.MORE_THEN_BEFORE) { DateTime earyer = inSecondStartTime.minus(this.time).withHourOfDay(1); if (!inFirstEndTime.isBefore(earyer)) { return new Event[] { this.secondEpisode }; } } return new Event[] {}; } public static enum RelationKind { IMMEDIATELY_BEFORE, BEFORE, FIXED_TIME_BEFORE, LESS_THEN_BEFORE, SAME_DAY_OF_YEAR, SAME_TIME_AS, MORE_THEN_BEFORE, BEFORE_SAME_DAY } public static class RelationXMLWriter extends IDedObjectXMLWriter<Relation> { @com.civprod.dynamicClassLoading.ClassInitalizer public static final void init() { XMLWriterImp.addXMLWriter(Relation.class, new RelationXMLWriter()); } @Override public Element writeElements(Relation ObjectToWrite) { Element newElement = new Element("Relation"); this.writeElements(ObjectToWrite, newElement); Element firstEpisodeElement = new Element("firstEventByID"); EventImp.EventIDXMLWriter.instance.writeElements(ObjectToWrite.firstEpisode, firstEpisodeElement); newElement.addContent(firstEpisodeElement); Element secondEpisodeElement = new Element("secondEventByID"); EventImp.EventIDXMLWriter.instance.writeElements(ObjectToWrite.secondEpisode, secondEpisodeElement); newElement.addContent(secondEpisodeElement); Element kindElement = new Element("kind"); kindElement.setText(ObjectToWrite.kind.name()); newElement.addContent(kindElement); if (ObjectToWrite.time != null) { Element TimeElement = new Element("time"); XMLWriter<ReadablePeriod> ReadablePeriodWriter = XMLWriterImp.getXMLWriter(ReadablePeriod.class); TimeElement.addContent(ReadablePeriodWriter.writeElements(ObjectToWrite.time)); newElement.addContent(TimeElement); } return newElement; } @Override public Relation<?, ?> readElements(org.jdom2.Element root) { return new Relation<>(root); } } }