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 files; /** * Add a new empty calendar to the given workspace and make it current. * Return the result.
      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:
        //
        // 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: 
        //
        // 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:
        //
        // 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);
}