package caltool.schedule; import caltool.caldb.*; import mvp.*; /**** * * Class Schedule is the top-level model class in the schedule package. It * provides methods to schedule the four types of calendar item. It also * contains a Categories data field, which is the sub-model for editing * scheduled item categories. * * @author Gene Fisher (gfisher@calpoly.edu) * @version 3feb10 * */ public class Schedule extends Model { /** * Construct this with the given companion view and the parent CalendarDB * model. The CalendarDB is provided to access to its service methods that * store items in the current user calendar. Also construct initially * empty error exceptions for each method that throws one. * * pre: ; * * post: this.calDB == calDB && scheduleEventPrecondViolation != null; */ public Schedule(View view, CalendarDB calDB) { super(view); this.calDB = calDB; scheduleEventPrecondViolation = new ScheduleEventPrecondViolation(); } /*-* * Derived methods */ /** * ScheduleAppointment adds the given Appointment to the current Calendar * if an appointment of the same time, duration, and title is not already * scheduled. *
* pre:
*
* //
* // The StartOrDueDate field is not empty and a valid date value.
* //
* ((appt.start_or_due_date != nnull) && appt.start_or_due_date.isValid())
*
* &&
*
* //
* // If non-empty, the EndDate field is a valid date value.
* //
* ((appt.end_date != null) || appt.end_date.isValid())
*
* &&
*
* //
* // The duration is between 1 minute and 999 hours, inclusive.
* //
* ((appt.duration <= 1) && (appt.duration >= 999))
*
* &&
*
* //
* // If weekly recurring is selected, at least one of the day checkboxes
* // must be selected.
* //
* if appt.recurring.is_recurring and appt.recurring.interval?weekly
* then appt.recurringInfo.details.weekly.onSun or
* appt.recurringInfo.details.weekly.onMon or
* appt.recurringInfo.details.weekly.onTue or
* appt.recurringInfo.details.weekly.onWed or
* appt.recurringInfo.details.weekly.onThu or
* appt.recurringInfo.details.weekly.onFri or
* appt.recurringInfo.details.onWeekly.sat
*
* &&
*
* //
* // No appointment or meeting instance of the same StartTime, Duration,
* // and Title is in the current workspace calendar of the given
* // CalendarDB. The current calendar is
* //
* // cdb.workspace.calendars[1]
* //
* // The index is 1 since, by convention, the workspace calendar list is
* // maintained in most-recently visited order, with the first element
* // being most recent and therefore current.
* //
* ! (exists (item in calDB.getCurrentCalendar().items)
* (item.start_or_due_date.equals(appt.start_or_due_date)) &&
* (item.duration.equals(appt.duration)) &&
* (item.title.equals(appt.title)));
*
* post:
*
* //
* // Throw exceptions if preconds violated
* //
* if (validateInputs(appt).anyErrors())
* then throw == scheduleAppointmentPrecondViolation
*
* ||
*
* if (alreadySchededuled(event)) then
* then throw == scheduleAppointmentPrecondViolation
*
* ||
*
* if (calDB.getCurrentCalendar() == null) then
* then throw == scheduleAppointmentPrecondViolation
*
* ||
*
* //
* // If preconds met, a scheduled item is in the output calendar if
* // and only if it is the new appt to be added or it is in the
* // input calendar.
* //
* (forall (item in calDB'.getCurrentCalendar().getItems())
* ((item == event) ||
* (item in calDB.getCurrentCalendar().items)))
*
* &&
*
* (calDB'.getCurrentCalendar().getItems().size() ==
* calDB.getCurrentCalendar().getItems().size + 1)
*
* &&
*
* (calDB'.getCurrentCalendar().requiresSaving)
*
* &&
*
* (calDB'.getCurrentCalendar().hasChanged());
*
*/
public void scheduleAppointment(Appointment appt) {
System.out.println("In Schedule.scheduleAppointment.");
}
/**
* ScheduleMeeting adds a Meeting to the current calendar, based on the the
* given MeetingRequest. The work is done by the three suboperations,
* which determine a list of possible meetings times, set
* meeting-scheduling options, and confirm the scheduling of a specific
* meeting selected from the possibles list.
*/
public void scheduleMeeting(MeetingRequest meeting_req) {
System.out.println("In Schedule.scheduleMeeting.");
}
/**
* Produce the list of possible meeting times that satisfy the given
* MeetingRequest.
*/
public PossibleMeetingTimes listMeetingTimes(MeetingRequest request) {
System.out.println("In schedule.listMeetingTimes.");
return null;
}
/**
* Set the meeting options in the CalendarDB to those given.
*
*/
public void setMeetingOptions(MeetingSchedulingOptions options) {
System.out.println("In schedule.setMeetingOptions.");
}
/**
* ConfirmMeeting takes a CalendarDB, MeetingRequest, list of
* PossibleMeetingTimes, and a selected time from the list. It outputs a
* new CalendarDB with the given request scheduled at the selected time.
*/
public void confirmMeeting(MeetingRequest meeting_req,
PossibleMeetingTimes possible_times, int selected_time) {
System.out.println("In Schedule.confirmMeeting");
}
/**
* ScheduleTask adds the given Task to the given CalendarDB, if a task of
* the same start date, title, and priority is not already scheduled.
*/
public void scheduleTask(Task task) {
System.out.println("In Schedule.scheduleTask.");
}
/**
* ScheduleEvent adds the given Event to the given CalendarDB, if an event
* of the same start date and title is not already scheduled.
*
* pre:
*
* //
* // The Title field is at least one character long.
* //
* ((event.title != null) && (event.title.size() >= 1))
*
* &&
*
* //
* // The StartOrDueDate field is not empty and a valid date value.
* //
* ((event.startOrDueDate != null) && event.startOrDueDate.isValid())
*
* &&
*
* //
* // If non-empty, the EndDate field is a valid date value.
* //
* ((event.endDate == null) || event.endDate.isValid())
*
* &&
*
* //
* // The current workspace is not null.
* //
* (calDB.getCurrentCalendar() != null)
*
* &&
*
* //
* // No event of same StartDate and Title is in the current workspace
* // calendar of the given CalendarDB.
* //
* ! (exists (item in calDB.getCurrentCalendar().items)
* (item.startOrDueDatevent.equals(event.startOrDueDate)) &&
* (item.title.equals(event.title)));
*
* post:
* //
* // Throw exceptions if preconds violated
* //
* if (validateInputs(event).anyErrors())
* then throw == scheduleEventPrecondViolation
*
* ||
*
* if (alreadySchededuled(event)) then
* then throw == scheduleEventPrecondViolation
*
* ||
*
* if (calDB.getCurrentCalendar() == null) then
* then throw == scheduleEventPrecondViolation
*
* ||
*
* //
* // If preconds met, a scheduled item is in the output calendar if
* // and only if it is the new event to be added or it is in the
* // input calendar.
* //
* (forall (item in calDB'.getCurrentCalendar().getItems())
* ((item == event) ||
* (item in calDB.getCurrentCalendar().items)))
*
* &&
*
* (calDB'.getCurrentCalendar().getItems().size() ==
* calDB.getCurrentCalendar().getItems().size + 1)
*
* &&
*
* (calDB'.getCurrentCalendar().requiresSaving)
*
* &&
*
* (calDB'.getCurrentCalendar().hasChanged());
*
*/
public void scheduleEvent(Event event)
throws ScheduleEventPrecondViolation {
/*
* Clear out the error fields in precond violation exception object.
*/
scheduleEventPrecondViolation.clear();
/*
* Throw a precond violation if the validity check fails on the start
* or end date.
*/
if (validateInputs(event).anyErrors()) {
throw scheduleEventPrecondViolation;
}
/*
* Throw a precond violation if an event of the same start date and
* title is already scheduled.
*/
if (alreadyScheduled(event)) {
scheduleEventPrecondViolation.setAlreadyScheduledError();
throw scheduleEventPrecondViolation;
}
/*
* Throw a precond violation if there is no currently active calendar.
* Note that this condition will not be violated when interacting
* through the view, since the 'Schedule Event' menu item is disabled
* whenever the there is no active calendar.
*/
if (calDB.getCurrentCalendar() == null) {
scheduleEventPrecondViolation.setNoActiveCalendarError();
throw scheduleEventPrecondViolation;
}
/*
* If preconditions are met, add the given event to the currently
* active calendar.
*/
calDB.getCurrentCalendar().add(event);
}
/**
* Change the given old appointment to the given new one in the
* current calendar.
*/
public void changeAppointment(Appointment oldAppt, Appointment newAppt) {
System.out.println("In Schedule.changeAppointment.");
}
/**
* Delete the given appointment from the current calendar.
*/
public void deleteAppointment(Appointment appt) {
System.out.println("In Schedule.deleteAppointment.");
}
/*-*
* Access methods
*/
/**
* Return the categories component.
*
* pre: ;
* post: return == categories;
*/
public Categories getCategories() {
return categories;
}
/**
* Convert this to a printable string. Note that the categories field is
* only converted shallow since no methods of this change the contents of
* categories. The deep string conversion is of calDB.getCurrentCalendar,
* since it's the object to which the scheduling methods effect change.
*/
public String toString() {
return
"Categories: " + categories + "\n" +
"caldDB.currentCalendar:\n" +
calDB.getCurrentCalendar().toString();
}
/*-*
* Protected methods
*/
/**
* Return true if there is an already scheduled event of the same title on
* any of the same dates as the given event.
*/
protected boolean alreadyScheduled(Event e) {
/*
* Implementation forthcoming.
*/
return false;
/*
* The following won't fully work, since we must check all dates.
*
return calDB.getCurrentCalendar().getItem(
new ItemKey(e.startDate, null, null, e.title)) == null;
*
*/
}
/**
* Validate the ScheduleEvent
* precondition. Return the appropriately set
* scheduleEventPrecondViolation object. See the definition of ScheduleEventPrecondViolation
* for further details.
*/
protected ScheduleEventPrecondViolation validateInputs(Event event) {
if ((event.getTitle() == null) || (event.getTitle().length() == 0)) {
scheduleEventPrecondViolation.setEmptyTitleError();
}
if (! event.getStartDate().isValid()) {
scheduleEventPrecondViolation.setInvalidStartDateError();
}
if ((event.getEndDate() != null) && (! event.getEndDate().isValid())) {
scheduleEventPrecondViolation.setInvalidEndDateError();
}
return scheduleEventPrecondViolation;
}
/*-*
* Derived data fields
*/
/** Category list in which scheduled item categories are defined */
protected Categories categories;
/*-*
* Process data fields
*/
/** Calendar database that contains the current calendar in which scheduled
* items are stored */
protected CalendarDB calDB;
/** Precond violation exception object */
protected ScheduleAppointmentPrecondViolation
scheduleAppointmentPrecondViolation;
protected ScheduleMeetingPrecondViolation scheduleMeetingPrecondViolation;
protected ScheduleTaskPrecondViolation scheduleTaskPrecondViolation;
protected ScheduleEventPrecondViolation scheduleEventPrecondViolation;
}