package net.sourceforge.fenixedu.domain; /** * * @author Manuel Pinto */ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Calendar; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.fortuna.ical4j.model.property.Location; import net.sourceforge.fenixedu.dataTransferObject.GenericPair; import net.sourceforge.fenixedu.domain.exceptions.DomainException; import net.sourceforge.fenixedu.domain.space.AllocatableSpace; import net.sourceforge.fenixedu.domain.space.Campus; import net.sourceforge.fenixedu.domain.space.LessonSpaceOccupation; import net.sourceforge.fenixedu.domain.time.calendarStructure.AcademicInterval; import net.sourceforge.fenixedu.domain.util.icalendar.EventBean; import net.sourceforge.fenixedu.presentationTier.Action.base.FenixAction; import net.sourceforge.fenixedu.util.DiaSemana; import net.sourceforge.fenixedu.util.HourMinuteSecond; import org.apache.commons.collections.comparators.ReverseComparator; import org.joda.time.DateTime; import org.joda.time.Interval; import org.joda.time.Minutes; import org.joda.time.YearMonthDay; import pt.ist.fenixWebFramework.security.accessControl.Checked; public class Lesson extends Lesson_Base { public static int NUMBER_OF_MINUTES_IN_HOUR = 60; public static int NUMBER_OF_DAYS_IN_WEEK = 7; public static final Comparator LESSON_COMPARATOR_BY_WEEKDAY_AND_STARTTIME = new Comparator() { @Override public int compare(Lesson o1, Lesson o2) { final int cd = o1.getDiaSemana().getDiaSemana().compareTo(o2.getDiaSemana().getDiaSemana()); if (cd != 0) { return cd; } final int cb = o1.getBeginHourMinuteSecond().compareTo(o2.getBeginHourMinuteSecond()); if (cb != 0) { return cb; } return DomainObject.COMPARATOR_BY_ID.compare(o1, o2); } }; @Checked("ResourceAllocationRolePredicates.checkPermissionsToManageLessons") public Lesson(DiaSemana diaSemana, Calendar inicio, Calendar fim, Shift shift, FrequencyType frequency, ExecutionSemester executionSemester, YearMonthDay beginDate, YearMonthDay endDate, AllocatableSpace room) { super(); OccupationPeriod period = null; if (shift != null) { GenericPair maxLessonsPeriod = shift.getExecutionCourse().getMaxLessonsPeriod(); if (beginDate == null || beginDate.isBefore(maxLessonsPeriod.getLeft())) { throw new DomainException("error.Lesson.invalid.begin.date"); } if (endDate == null || endDate.isAfter(maxLessonsPeriod.getRight())) { throw new DomainException("error.invalid.new.date"); } period = OccupationPeriod.readOccupationPeriod(beginDate, endDate); if (period == null) { period = new OccupationPeriod(beginDate, endDate); } } setRootDomainObject(RootDomainObject.getInstance()); setDiaSemana(diaSemana); setInicio(inicio); setFim(fim); setShift(shift); setFrequency(frequency); setPeriod(period); checkShiftLoad(shift); if (room != null) { new LessonSpaceOccupation(room, this); } } @Checked("ResourceAllocationRolePredicates.checkPermissionsToManageLessons") public void edit(YearMonthDay newBeginDate, YearMonthDay newEndDate, DiaSemana diaSemana, Calendar inicio, Calendar fim, FrequencyType frequency, Boolean createLessonInstances, AllocatableSpace newRoom) { if (newBeginDate != null && newEndDate != null && newBeginDate.isAfter(newEndDate)) { throw new DomainException("error.Lesson.new.begin.date.after.new.end.date"); } GenericPair maxLessonsPeriod = getShift().getExecutionCourse().getMaxLessonsPeriod(); if (newBeginDate == null || newBeginDate.isBefore(maxLessonsPeriod.getLeft())) { throw new DomainException("error.Lesson.invalid.new.begin.date"); } if (newEndDate == null || newEndDate.isAfter(maxLessonsPeriod.getRight())) { throw new DomainException("error.invalid.new.end.date"); } refreshPeriodAndInstancesInEditOperation(newBeginDate, newEndDate, createLessonInstances, maxLessonsPeriod); if (wasFinished() && (hasLessonSpaceOccupation() || !hasAnyLessonInstances())) { throw new DomainException("error.Lesson.empty.period"); } setDiaSemana(diaSemana); setInicio(inicio); setFim(fim); setFrequency(frequency); checkShiftLoad(getShift()); lessonSpaceOccupationManagement(newRoom); } @Checked("ResourceAllocationRolePredicates.checkPermissionsToManageLessons") public void delete() { final Shift shift = getShift(); final boolean isLastLesson = isLastLesson(shift); if (isLastLesson && shift.hasAnyStudentsInAssociatedStudentGroups()) { throw new DomainException("error.deleteLesson.with.Shift.with.studentGroups", prettyPrint()); } if (isLastLesson && shift.hasAnyStudents()) { throw new DomainException("error.deleteLesson.with.Shift.with.students", prettyPrint()); } if (hasAnyAssociatedSummaries()) { throw new DomainException("error.deleteLesson.with.summaries", prettyPrint()); } final OccupationPeriod period = getPeriod(); super.setPeriod(null); if (period != null) { period.delete(); } if (hasLessonSpaceOccupation()) { getLessonSpaceOccupation().delete(); } while (hasAnyLessonInstances()) { getLessonInstances().get(0).delete(); } super.setShift(null); removeRootDomainObject(); deleteDomainObject(); } private boolean isLastLesson(final Shift shift) { for (final Lesson lesson : shift.getAssociatedLessonsSet()) { if (lesson != this) { return false; } } return true; } @jvstm.cps.ConsistencyPredicate protected boolean checkRequiredParameters() { return getFrequency() != null && getDiaSemana() != null; } @jvstm.cps.ConsistencyPredicate protected boolean checkTimeInterval() { final HourMinuteSecond start = getBeginHourMinuteSecond(); final HourMinuteSecond end = getEndHourMinuteSecond(); return start != null && end != null && start.isBefore(end); } private void lessonSpaceOccupationManagement(AllocatableSpace newRoom) { LessonSpaceOccupation lessonSpaceOccupation = getLessonSpaceOccupation(); if (newRoom != null) { if (!wasFinished()) { if (lessonSpaceOccupation == null) { lessonSpaceOccupation = new LessonSpaceOccupation(newRoom, this); } else { lessonSpaceOccupation.edit(newRoom); } } } else { if (lessonSpaceOccupation != null) { lessonSpaceOccupation.delete(); } } } @Override public void setShift(Shift shift) { if (shift == null) { throw new DomainException("error.Lesson.empty.shift"); } super.setShift(shift); } @Override public void setFrequency(FrequencyType frequency) { if (frequency == null) { throw new DomainException("error.Lesson.empty.type"); } super.setFrequency(frequency); } @Override public void setPeriod(OccupationPeriod period) { if (period == null) { throw new DomainException("error.Lesson.empty.period"); } super.setPeriod(period); } public boolean wasFinished() { return !hasPeriod(); } public ExecutionCourse getExecutionCourse() { return getShift().getExecutionCourse(); } public ExecutionSemester getExecutionPeriod() { return getShift().getExecutionPeriod(); } public AllocatableSpace getSala() { if (hasLessonSpaceOccupation()) { return getLessonSpaceOccupation().getRoom(); } else if (hasAnyLessonInstances() && wasFinished()) { return getLastLessonInstance().getRoom(); } return null; } public boolean hasSala() { return getSala() != null; } public void deleteLessonInstanceIn(YearMonthDay day) { // throw new UnsupportedOperationException(); if (day == null) { return; } LessonInstance lessonInstance = getLessonInstanceFor(day); if (lessonInstance == null) { throw new UnsupportedOperationException(); // if (!wasFinished() && // !getPeriod().getStartYearMonthDay().isAfter(day)) { // edit(day.plusDays(1), // getPeriod().getLastOccupationPeriodOfNestedPeriods().getEndYearMonthDay(), // getDiaSemana(), // getInicio(), getFim(), getFrequency(), true, day); // } } else { lessonInstance.delete(); } } public void refreshPeriodAndInstancesInSummaryCreation(YearMonthDay newBeginDate) { if (!wasFinished() && newBeginDate != null && newBeginDate.isAfter(getPeriod().getStartYearMonthDay())) { SortedSet instanceDates = getAllLessonInstancesDatesToCreate(getLessonStartDay(), newBeginDate .minusDays(1), true); YearMonthDay newEndDate = getPeriod().getLastOccupationPeriodOfNestedPeriods().getEndYearMonthDay(); if (!newBeginDate.isAfter(newEndDate)) { refreshPeriod(newBeginDate, getPeriod().getLastOccupationPeriodOfNestedPeriods().getEndYearMonthDay()); } else { OccupationPeriod period = getPeriod(); removeLessonSpaceOccupationAndPeriod(); period.delete(); } createAllLessonInstances(instanceDates); } } private void refreshPeriodAndInstancesInEditOperation(YearMonthDay newBeginDate, YearMonthDay newEndDate, Boolean createLessonInstances, GenericPair maxLessonsPeriod) { removeExistentInstancesWithoutSummaryAfterOrEqual(newBeginDate); SortedSet instanceDates = getAllLessonInstancesDatesToCreate(getLessonStartDay(), newBeginDate.minusDays(1), createLessonInstances); refreshPeriod(newBeginDate, newEndDate); createAllLessonInstances(instanceDates); } private void createAllLessonInstances(SortedSet instanceDates) { for (YearMonthDay day : instanceDates) { new LessonInstance(this, day); } } private SortedSet getAllLessonInstancesDatesToCreate(YearMonthDay startDate, YearMonthDay endDate, Boolean createLessonInstances) { if (startDate != null && endDate != null && !startDate.isAfter(endDate) && createLessonInstances) { SortedSet possibleLessonDates = getAllValidLessonDatesWithoutInstancesDates(startDate, endDate); List allLessonInstancesUntil = getAllLessonInstancesUntil(endDate); for (LessonInstance lessonInstance : allLessonInstancesUntil) { possibleLessonDates.remove(lessonInstance.getDay()); } return possibleLessonDates; } return new TreeSet(); } private void removeExistentInstancesWithoutSummaryAfterOrEqual(YearMonthDay newBeginDate) { Map> instances = getLessonInstancesAfterOrEqual(newBeginDate); if (instances.get(Boolean.TRUE).isEmpty()) { List instancesWithoutSummary = instances.get(Boolean.FALSE); for (Iterator iter = instancesWithoutSummary.iterator(); iter.hasNext();) { LessonInstance instance = iter.next(); iter.remove(); instance.delete(); } } else { throw new DomainException("error.Lesson.invalid.new.begin.date"); } } private Map> getLessonInstancesAfterOrEqual(YearMonthDay day) { Map> result = new HashMap>(); result.put(Boolean.TRUE, new ArrayList()); result.put(Boolean.FALSE, new ArrayList()); if (day != null) { List lessonInstances = getLessonInstances(); for (LessonInstance lessonInstance : lessonInstances) { if (lessonInstance.hasSummary() && !lessonInstance.getDay().isBefore(day)) { List list = result.get(Boolean.TRUE); list.add(lessonInstance); } else if (!lessonInstance.hasSummary() && !lessonInstance.getDay().isBefore(day)) { List list = result.get(Boolean.FALSE); list.add(lessonInstance); } } } return result; } private void refreshPeriod(YearMonthDay newBeginDate, YearMonthDay newEndDate) { if (newBeginDate != null && newEndDate != null && !newBeginDate.isAfter(newEndDate)) { boolean newPeriod = false; OccupationPeriod currentPeriod = getPeriod(); OccupationPeriod oldFirstPeriod = currentPeriod; if (currentPeriod == null || !currentPeriod.hasNextPeriod()) { setPeriod(new OccupationPeriod(newBeginDate, newEndDate)); newPeriod = true; } else { while (currentPeriod != null) { if (currentPeriod.getStartYearMonthDay().isAfter(newEndDate)) { newPeriod = false; break; } if (!currentPeriod.getEndYearMonthDay().isBefore(newBeginDate)) { if (!currentPeriod.getStartYearMonthDay().isAfter(newBeginDate)) { setPeriod(getNewNestedPeriods(currentPeriod, newBeginDate, newEndDate)); } else { if (currentPeriod.equals(oldFirstPeriod)) { setPeriod(getNewNestedPeriods(currentPeriod, newBeginDate, newEndDate)); } else { setPeriod(getNewNestedPeriods(currentPeriod, currentPeriod.getStartYearMonthDay(), newEndDate)); } } newPeriod = true; break; } currentPeriod = currentPeriod.getNextPeriod(); } } if (!newPeriod) { removeLessonSpaceOccupationAndPeriod(); } if (oldFirstPeriod != null) { oldFirstPeriod.delete(); } } } private OccupationPeriod getNewNestedPeriods(OccupationPeriod currentPeriod, YearMonthDay newBeginDate, YearMonthDay newEndDate) { if (!currentPeriod.getEndYearMonthDay().isBefore(newEndDate)) { return new OccupationPeriod(newBeginDate, newEndDate); } else { OccupationPeriod newPeriod = new OccupationPeriod(newBeginDate, currentPeriod.getEndYearMonthDay()); OccupationPeriod newPeriodPointer = newPeriod; while (currentPeriod.hasNextPeriod()) { if (currentPeriod.getNextPeriod().getStartYearMonthDay().isAfter(newEndDate)) { break; } if (!currentPeriod.getNextPeriod().getEndYearMonthDay().isBefore(newEndDate)) { OccupationPeriod newNextPeriod = new OccupationPeriod(currentPeriod.getNextPeriod().getStartYearMonthDay(), newEndDate); newPeriodPointer.setNextPeriod(newNextPeriod); break; } else { OccupationPeriod newNextPeriod = new OccupationPeriod(currentPeriod.getNextPeriod().getStartYearMonthDay(), currentPeriod.getNextPeriod().getEndYearMonthDay()); newPeriodPointer.setNextPeriod(newNextPeriod); newPeriodPointer = newNextPeriod; currentPeriod = currentPeriod.getNextPeriod(); } } return newPeriod; } } private void removeLessonSpaceOccupationAndPeriod() { if (hasLessonSpaceOccupation()) { getLessonSpaceOccupation().delete(); } super.setPeriod(null); } public LessonSpaceOccupation getRoomOccupation() { return getLessonSpaceOccupation(); } private int getUnitMinutes() { return Minutes.minutesBetween(getBeginHourMinuteSecond(), getEndHourMinuteSecond()).getMinutes(); } public BigDecimal getTotalHours() { return getUnitHours().multiply(BigDecimal.valueOf(getFinalNumberOfLessonInstances())); } public BigDecimal getUnitHours() { return BigDecimal.valueOf(getUnitMinutes()) .divide(BigDecimal.valueOf(NUMBER_OF_MINUTES_IN_HOUR), 2, RoundingMode.HALF_UP); } public String getInicioString() { return String.valueOf(getInicio().get(Calendar.HOUR_OF_DAY)); } public double hoursAfter(int hour) { HourMinuteSecond afterHour = new HourMinuteSecond(hour, 0, 0); if (!getBeginHourMinuteSecond().isBefore(afterHour)) { return getUnitHours().doubleValue(); } else if (getEndHourMinuteSecond().isAfter(afterHour)) { return BigDecimal.valueOf(Minutes.minutesBetween(afterHour, getEndHourMinuteSecond()).getMinutes()).divide( BigDecimal.valueOf(NUMBER_OF_MINUTES_IN_HOUR), 2, RoundingMode.HALF_UP).doubleValue(); } return 0.0; } public Summary getSummaryByDate(YearMonthDay date) { for (Summary summary : getAssociatedSummaries()) { if (summary.getSummaryDateYearMonthDay().isEqual(date)) { return summary; } } return null; } public List getAssociatedSummaries() { List result = new ArrayList(); List lessonInstances = getLessonInstances(); for (LessonInstance lessonInstance : lessonInstances) { if (lessonInstance.hasSummary()) { result.add(lessonInstance.getSummary()); } } return result; } public boolean hasAnyAssociatedSummaries() { return !getAssociatedSummaries().isEmpty(); } public SortedSet getSummariesSortedByDate() { return getSummaries(new ReverseComparator(Summary.COMPARATOR_BY_DATE_AND_HOUR)); } public SortedSet getSummariesSortedByNewestDate() { return getSummaries(Summary.COMPARATOR_BY_DATE_AND_HOUR); } public boolean isTimeValidToInsertSummary(HourMinuteSecond timeToInsert, YearMonthDay summaryDate) { YearMonthDay currentDate = new YearMonthDay(); if (timeToInsert == null || summaryDate == null || summaryDate.isAfter(currentDate)) { return false; } if (currentDate.isEqual(summaryDate)) { HourMinuteSecond lessonEndTime = null; LessonInstance lessonInstance = getLessonInstanceFor(summaryDate); lessonEndTime = lessonInstance != null ? lessonInstance.getEndTime() : getEndHourMinuteSecond(); return !lessonEndTime.isAfter(timeToInsert); } return true; } public boolean isDateValidToInsertSummary(YearMonthDay date) { YearMonthDay currentDate = new YearMonthDay(); SortedSet allLessonDatesEvenToday = getAllLessonDatesUntil(currentDate); return (allLessonDatesEvenToday.isEmpty() || date == null) ? false : allLessonDatesEvenToday.contains(date); } public boolean isDateValidToInsertExtraSummary(YearMonthDay date) { return !(getLessonStartDay().isAfter(date) || getLessonEndDay().isBefore(date)); } private YearMonthDay getLessonStartDay() { if (!wasFinished()) { YearMonthDay periodBegin = getPeriod().getStartYearMonthDay(); return getValidBeginDate(periodBegin); } return null; } private YearMonthDay getLessonEndDay() { if (!wasFinished()) { YearMonthDay periodEnd = getPeriod().getLastOccupationPeriodOfNestedPeriods().getEndYearMonthDay(); return getValidEndDate(periodEnd); } return null; } private YearMonthDay getValidBeginDate(YearMonthDay startDate) { YearMonthDay lessonBegin = startDate.toDateTimeAtMidnight().withDayOfWeek( getDiaSemana().getDiaSemanaInDayOfWeekJodaFormat()).toYearMonthDay(); if (lessonBegin.isBefore(startDate)) { lessonBegin = lessonBegin.plusDays(NUMBER_OF_DAYS_IN_WEEK); } return lessonBegin; } private YearMonthDay getValidEndDate(YearMonthDay endDate) { YearMonthDay lessonEnd = endDate.toDateTimeAtMidnight().withDayOfWeek(getDiaSemana().getDiaSemanaInDayOfWeekJodaFormat()) .toYearMonthDay(); if (lessonEnd.isAfter(endDate)) { lessonEnd = lessonEnd.minusDays(NUMBER_OF_DAYS_IN_WEEK); } return lessonEnd; } public Campus getLessonCampus() { if (!wasFinished()) { return hasSala() ? getSala().getSpaceCampus() : null; } else { LessonInstance lastLessonInstance = getLastLessonInstance(); return lastLessonInstance != null && lastLessonInstance.getRoom() != null ? lastLessonInstance.getRoom() .getSpaceCampus() : null; } } public YearMonthDay getNextPossibleSummaryDate() { YearMonthDay currentDate = new YearMonthDay(); HourMinuteSecond now = new HourMinuteSecond(); Summary lastSummary = getLastSummary(); if (lastSummary != null) { SortedSet datesEvenToday = getAllLessonDatesUntil(currentDate); SortedSet possibleDates = datesEvenToday.tailSet(lastSummary.getSummaryDateYearMonthDay()); possibleDates.remove(lastSummary.getSummaryDateYearMonthDay()); if (!possibleDates.isEmpty()) { YearMonthDay nextPossibleDate = possibleDates.first(); return isTimeValidToInsertSummary(now, nextPossibleDate) ? nextPossibleDate : null; } } else { YearMonthDay nextPossibleDate = hasAnyLessonInstances() ? getFirstLessonInstance().getDay() : getLessonStartDay(); return isTimeValidToInsertSummary(now, nextPossibleDate) ? nextPossibleDate : null; } return null; } public SortedSet getAllPossibleDatesToInsertSummary() { HourMinuteSecond now = new HourMinuteSecond(); YearMonthDay currentDate = new YearMonthDay(); SortedSet datesToInsert = getAllLessonDatesUntil(currentDate); for (Summary summary : getAssociatedSummaries()) { YearMonthDay summaryDate = summary.getSummaryDateYearMonthDay(); datesToInsert.remove(summaryDate); } for (Iterator iter = datesToInsert.iterator(); iter.hasNext();) { YearMonthDay date = iter.next(); if (!isTimeValidToInsertSummary(now, date)) { iter.remove(); } } return datesToInsert; } public SortedSet getAllLessonDatesWithoutInstanceDates() { SortedSet dates = new TreeSet(); if (!wasFinished()) { YearMonthDay startDateToSearch = getLessonStartDay(); YearMonthDay endDateToSearch = getLessonEndDay(); dates.addAll(getAllValidLessonDatesWithoutInstancesDates(startDateToSearch, endDateToSearch)); } return dates; } public SortedSet getAllLessonDates() { SortedSet dates = getAllLessonInstanceDates(); if (!wasFinished()) { YearMonthDay startDateToSearch = getLessonStartDay(); YearMonthDay endDateToSearch = getLessonEndDay(); dates.addAll(getAllValidLessonDatesWithoutInstancesDates(startDateToSearch, endDateToSearch)); } return dates; } public int getFinalNumberOfLessonInstances() { int count = getLessonInstancesCount(); if (!wasFinished()) { YearMonthDay startDateToSearch = getLessonStartDay(); YearMonthDay endDateToSearch = getLessonEndDay(); count += getAllValidLessonDatesWithoutInstancesDates(startDateToSearch, endDateToSearch).size(); } return count; } private SortedSet getAllLessonDatesUntil(YearMonthDay day) { SortedSet result = new TreeSet(); if (day != null) { result.addAll(getAllLessonInstanceDatesUntil(day)); if (!wasFinished()) { YearMonthDay startDateToSearch = getLessonStartDay(); YearMonthDay lessonEndDay = getLessonEndDay(); YearMonthDay endDateToSearch = (lessonEndDay.isAfter(day)) ? day : lessonEndDay; result.addAll(getAllValidLessonDatesWithoutInstancesDates(startDateToSearch, endDateToSearch)); } } return result; } public SortedSet getAllLessonInstanceDates() { SortedSet dates = new TreeSet(); for (LessonInstance instance : getLessonInstances()) { dates.add(instance.getDay()); } return dates; } public List getAllLessonInstancesUntil(YearMonthDay day) { List result = new ArrayList(); if (day != null) { for (LessonInstance instance : getLessonInstances()) { if (!instance.getDay().isAfter(day)) { result.add(instance); } } } return result; } public SortedSet getAllLessonInstanceDatesUntil(YearMonthDay day) { SortedSet result = new TreeSet(); if (day != null) { for (LessonInstance instance : getLessonInstances()) { YearMonthDay instanceDay = instance.getDay(); if (!instanceDay.isAfter(day)) { result.add(instanceDay); } } } return result; } private SortedSet getAllValidLessonDatesWithoutInstancesDates(YearMonthDay startDateToSearch, YearMonthDay endDateToSearch) { SortedSet result = new TreeSet(); startDateToSearch = startDateToSearch != null ? getValidBeginDate(startDateToSearch) : null; if (!wasFinished() && startDateToSearch != null && endDateToSearch != null && !startDateToSearch.isAfter(endDateToSearch)) { Campus lessonCampus = getLessonCampus(); while (true) { if (isDayValid(startDateToSearch, lessonCampus)) { result.add(startDateToSearch); } startDateToSearch = startDateToSearch.plusDays(getNumberOfDaysToSumBetweenTwoLessons()); if (startDateToSearch.isAfter(endDateToSearch)) { break; } } } return result; } private boolean isDayValid(YearMonthDay day, Campus lessonCampus) { return !Holiday.isHoliday(day.toLocalDate(), lessonCampus) && getPeriod().nestedOccupationPeriodsContainsDay(day); } public YearMonthDay getNextPossibleLessonInstanceDate() { SortedSet allLessonDates = getAllLessonDates(); LessonInstance lastLessonInstance = getLastLessonInstance(); if (lastLessonInstance != null) { YearMonthDay day = lastLessonInstance.getDay(); SortedSet nextLessonDates = allLessonDates.tailSet(day); nextLessonDates.remove(day); return nextLessonDates.isEmpty() ? null : nextLessonDates.first(); } return allLessonDates.isEmpty() ? null : allLessonDates.first(); } public LessonInstance getLastLessonInstance() { SortedSet result = new TreeSet(LessonInstance.COMPARATOR_BY_BEGIN_DATE_TIME); result.addAll(getLessonInstances()); return !result.isEmpty() ? result.last() : null; } public LessonInstance getFirstLessonInstance() { SortedSet result = new TreeSet(LessonInstance.COMPARATOR_BY_BEGIN_DATE_TIME); result.addAll(getLessonInstances()); return !result.isEmpty() ? result.first() : null; } private Summary getLastSummary() { SortedSet summaries = getSummariesSortedByNewestDate(); return (summaries.isEmpty()) ? null : summaries.first(); } private SortedSet getSummaries(Comparator comparator) { SortedSet lessonSummaries = new TreeSet(comparator); lessonSummaries.addAll(getAssociatedSummaries()); return lessonSummaries; } private int getNumberOfDaysToSumBetweenTwoLessons() { return getFrequency().getNumberOfDays(); } public LessonInstance getLessonInstanceFor(YearMonthDay date) { List lessonInstances = getLessonInstances(); for (LessonInstance lessonInstance : lessonInstances) { if (lessonInstance.getDay().isEqual(date)) { return lessonInstance; } } return null; } public boolean contains(Interval interval) { return contains(interval, getAllLessonDates()); } public boolean isAllIntervalIn(Interval interval) { return isAllIntervalIn(interval, getAllLessonDates()); } public boolean containsWithoutCheckInstanceDates(Interval interval) { return contains(interval, getAllLessonDatesWithoutInstanceDates()); } private boolean isAllIntervalIn(Interval interval, SortedSet allLessonDates) { YearMonthDay intervalStartDate = interval.getStart().toYearMonthDay(); YearMonthDay intervalEndDate = interval.getEnd().toYearMonthDay(); HourMinuteSecond intervalBegin = new HourMinuteSecond(interval.getStart().getHourOfDay(), interval.getStart() .getMinuteOfHour(), 0); HourMinuteSecond intervalEnd = new HourMinuteSecond(interval.getEnd().getHourOfDay(), interval.getEnd().getMinuteOfHour(), 0); for (YearMonthDay day : allLessonDates) { if (intervalStartDate.isEqual(intervalEndDate)) { if (day.isEqual(intervalStartDate) && !intervalBegin.isBefore(getBeginHourMinuteSecond()) && !intervalEnd.isAfter(getEndHourMinuteSecond())) { return true; } } } return false; } private boolean contains(Interval interval, SortedSet allLessonDates) { YearMonthDay intervalStartDate = interval.getStart().toYearMonthDay(); YearMonthDay intervalEndDate = interval.getEnd().toYearMonthDay(); HourMinuteSecond intervalBegin = new HourMinuteSecond(interval.getStart().getHourOfDay(), interval.getStart() .getMinuteOfHour(), interval.getStart().getSecondOfMinute()); HourMinuteSecond intervalEnd = new HourMinuteSecond(interval.getEnd().getHourOfDay(), interval.getEnd().getMinuteOfHour(), interval.getEnd().getSecondOfMinute()); for (YearMonthDay day : allLessonDates) { if (intervalStartDate.isEqual(intervalEndDate)) { if (day.isEqual(intervalStartDate) && !intervalBegin.isAfter(getEndHourMinuteSecond()) && !intervalEnd.isBefore(getBeginHourMinuteSecond())) { return true; } } else { if ((day.isAfter(intervalStartDate) && day.isBefore(intervalEndDate)) || day.isEqual(intervalStartDate) && !getEndHourMinuteSecond().isBefore(intervalBegin) || (day.isEqual(intervalEndDate) && !getBeginHourMinuteSecond().isAfter(intervalEnd))) { return true; } } } return false; } public String prettyPrint() { final StringBuilder result = new StringBuilder(); result.append(getDiaSemana().toString()).append(" ("); result.append(getBeginHourMinuteSecond().toString("HH:mm")).append("-"); result.append(getEndHourMinuteSecond().toString("HH:mm")).append(") "); result.append(hasSala() ? (getSala()).getName().toString() : ""); return result.toString(); } private void checkShiftLoad(Shift shift) { if (shift != null) { List courseLoads = shift.getCourseLoads(); if (courseLoads.size() == 1) { CourseLoad courseLoad = courseLoads.get(0); if (courseLoad.getUnitQuantity() != null && getUnitHours().compareTo(courseLoad.getUnitQuantity()) != 0) { throw new DomainException("error.Lesson.shift.load.unit.quantity.exceeded", getUnitHours().toString(), courseLoad.getUnitQuantity().toString()); } if (shift.getTotalHours().compareTo(courseLoad.getTotalQuantity()) == 1) { throw new DomainException("error.Lesson.shift.load.total.quantity.exceeded", shift.getTotalHours().toString(), courseLoad.getTotalQuantity().toString()); } } else if (courseLoads.size() > 1) { boolean unitValid = false, totalValid = false; BigDecimal lessonHours = getUnitHours(); BigDecimal totalHours = shift.getTotalHours(); for (CourseLoad courseLoad : courseLoads) { unitValid = false; totalValid = false; if (courseLoad.getUnitQuantity() == null || lessonHours.compareTo(courseLoad.getUnitQuantity()) == 0) { unitValid = true; } if (totalHours.compareTo(courseLoad.getTotalQuantity()) != 1) { totalValid = true; if (unitValid) { break; } } } if (!totalValid) { throw new DomainException("error.Lesson.shift.load.total.quantity.exceeded.2", shift.getTotalHours() .toString()); } if (!unitValid) { throw new DomainException("error.Lesson.shift.load.unit.quantity.exceeded.2", getUnitHours().toString()); } } } } public Calendar getInicio() { if (this.getBegin() != null) { Calendar result = Calendar.getInstance(); result.setTime(this.getBegin()); return result; } return null; } public void setInicio(Calendar inicio) { if (inicio != null) { this.setBegin(inicio.getTime()); } else { this.setBegin(null); } } public Calendar getFim() { if (this.getEnd() != null) { Calendar result = Calendar.getInstance(); result.setTime(this.getEnd()); return result; } return null; } public void setFim(Calendar fim) { if (fim != null) { this.setEnd(fim.getTime()); } else { this.setEnd(null); } } public AcademicInterval getAcademicInterval() { return getExecutionPeriod().getAcademicInterval(); } public List getAllLessonsEvents(String scheme, String serverName, int serverPort) { HashMap hashmap = new HashMap(); ArrayList result = new ArrayList(); for (LessonInstance lessonInstance : getAllLessonInstancesUntil(getLessonEndDay())) { hashmap.put(lessonInstance.getBeginDateTime(), lessonInstance); } for (YearMonthDay aDay : getAllLessonDates()) { DateTime beginDate = new DateTime(aDay.getYear(), aDay.getMonthOfYear(), aDay.getDayOfMonth(), getBeginHourMinuteSecond().getHour(), getBeginHourMinuteSecond().getMinuteOfHour(), getBeginHourMinuteSecond().getSecondOfMinute(), 0); LessonInstance lessonInstance = hashmap.get(beginDate); EventBean bean; String location = null; String url = scheme + "://" + serverName + ((serverPort == 80 || serverPort == 443) ? "" : ":" + serverPort) + getExecutionCourse().getSite().getReversePath(); if (lessonInstance != null) { if (lessonInstance.getLessonInstanceSpaceOccupation() != null) { location = lessonInstance.getLessonInstanceSpaceOccupation().getRoom().getName(); } String summary = null; if (lessonInstance.getSummary() != null) { summary = lessonInstance.getSummary().getSummaryText().toString(); Pattern p = Pattern.compile("<[a-zA-Z0-9\\/]*[^>]*>"); Matcher matcher = p.matcher(summary); summary = matcher.replaceAll(""); p = Pattern.compile("\\s(\\s)*"); matcher = p.matcher(summary); summary = matcher.replaceAll(" "); } bean = new EventBean(getShift().getExecutionCourse().getNome() + " : " + getShift().getShiftTypesCapitalizedPrettyPrint(), lessonInstance.getBeginDateTime(), lessonInstance .getEndDateTime(), false, location, url + "/sumarios", summary); } else { if (getLessonSpaceOccupation() != null) { location = getLessonSpaceOccupation().getRoom().getName(); } DateTime endDate = new DateTime(aDay.getYear(), aDay.getMonthOfYear(), aDay.getDayOfMonth(), getEndHourMinuteSecond().getHour(), getEndHourMinuteSecond().getMinuteOfHour(), getEndHourMinuteSecond() .getSecondOfMinute(), 0); bean = new EventBean(getShift().getExecutionCourse().getNome() + " : " + getShift().getShiftTypesCapitalizedPrettyPrint(), beginDate, endDate, false, location, url, null); } result.add(bean); } return result; } }