package file; import java.util.Collection; import caldb.*; /**** * A FileSpace is an abstract model of a file space in the operating * environment in which the CalendarTool is run. The FileSpace is simply a * collection of zero or more Files, with no other properties modeled here. * * All of the FileSpace methods operate parametrically with and on a * UserWorkSpace. Callers send in a workspace and capture the modified * return value as appropriate to the calling context. The expectation is that * the caller is responding to a user request to perform an operation on the * currently active workspace in which the user is operating. */ abstract class FileSpace { /** As noted in the class-level comment, a the highly-abstract data * represenation of a file space is simply a collection of files. */ Collection<File> files; /** * Add a new empty calendar to the given workspace and make it current. * Return the result. <pre> post: // The output workspace has a new empty calendar and that calendar is // current. The settings and user id of the new calendar are those of // the workspace. The file is empty. The name is unique, per the // logic defined in isUniqueName, which requires a unique numeric // suffix if necessary for disambiguation. The selected calendar date // is today and the calendar does not require saving. The calendars in // positions 1-last in the the input workspace are in positions // 2-last+1 in the output workspace. All other calendars in the input // workspace are in the output workspace, and nothing else is. exists (UserCalendar uc ; (uc.items == null) && (return.calendars.get(0) == uc) && (uc.settings.equals(uws.settings.cal)) && (uc.uid.equals(uws.uid)) && (uc.file == null) && isUniqueName(uws, return, uc) && (uc.selected_date).equals(today()) && (! uc.requires_saving) && forall (int i ; (i >= 1) && (i <= uws.calendars.size()) ; return.calendars.get(i+1).equals(uws.calendars.get(i))) && forall (UserCalendar uc_other ; return.calendars.contains(uc_other) && uc_other.equals(uc) || uws.calendars.contains(uc))); */ abstract UserWorkSpace fileNew(UserWorkSpace uws); /** * Open an existing calendar file of the given name and put the data from * that file in the workspace. <pre> pre: // // A file of the given name exists in the given file space, the file // is readable, and the file's data are of type calendar. // exists (File file ; fs.contains(file) ; (file.name.equals(fn)) && file.permissions.is_readable && file.file_type == CALENDAR_TYPE); post: // // The output workspace has a new calendar containing the file data of // the input file, and that calendar is current. The user id of the // new calendar is that of the workspace, the options are the given // global options input, and the calendar does not require saving. The // calendars in positions 1-last in the the input workspace are in // positions 2-last+1 in the output workspace. // exists (uc:UserCalendar ; (uc.equals(uws'.calendars.get(0))) && (exists (File file; fs.contains(file) ; (file.name.equals(fn)) && (uc.equals(file.data)) ) && (uc.uid.equals(uws.uid)) && isUniqueName(uws, uws', uc) && (uc.selected_date).equals(today()) && (not uc.requires_saving) && (uws'.calendars.size().equals(uws.calendars.size() + 1)) && (forall (int i ; (i >= 2) && (i <= #(uws.calendars))) uws'.calendars.get(i+1).equals(uws.calendars.get(i+1)) ) ); */ abstract void open(FileSpace fs, String fn, UserWorkSpace uws); /** Close the current calendar if it does not require saving. <pre> pre: // // The calendar does not require saving. // ! (uws.calendars.get(0).requires_saving); post: // // The current calendar is deleted from the workspace. The remaining // calendars, if any, are shifted in position in the list one position // earlier. // (! (uws'.calendars.contains(uws.calendars.get(0)) && (uws'.calendars.sizd().equals(uws.calendars.size() - 1)) && forall (int i ; (i >= 1) && (i < #(uws.calendars))) uws'.calendars.get(i) == uws.calendars.get(i+1); ); */ abstract void close(FileSpace fs, UserWorkSpace uws); /** * If the calendar in the given workspace requires saving, save it in the * given file space. <pre> pre: // // The given workspace requires saving. Also, there is a writable // file of the current workspace filename in the given FileSpace. Note // that the only way the current file could be unwritable is through an // external change to the file space since the file was opened by the // Calendar Tool. Note further that this precondition disallows the // case where the current calendar file has been externally deleted // since it was opened by the calendar tool. That is, the file must // both exist and be writable at the time the save is attempted. // (uws.calendars.get(0).requires_saving) && exists (file File; fs.contains(file) ; (file.name.equals(uws.calendars.get(0).file.name)) && (file.permissions.is_writable)); post: // // There is a calendar-type file in the resulting FileSpace containing // the current workspace calendar as its file data. In the resulting // workspace, the requires saving indicator is false. // exists (File file; fs'.contains(file) ; (file.name.equals(uws'.calendars.get(0).file.name)) && (file.data.equals(uws'.calendars.get(0))) && (file.permissions.is_writable) && (file.file_type == CALENDAR_TYPE) && (not uws'.calendars.get(0).requires_saving) ); */ abstract void save(FileSpace fs, UserWorkSpace uws); /** * If the name of the given user calendar is not unique in the given * workspace uws, then suffix it with a unique integer. The integer is * one greater than the suffix of same-name calendar with the largest * suffix in uws. If name of the given calendar is unique in uws, then * its name suffix is null. * post: // Left as exercise for the reader */ abstract boolean isUniqueName(UserWorkSpace uws, UserCalendar uc); }