5.4. File (File.rsl)

(****
 *
 * Module File defines the objects and operations related to file processing
 * in the CSTutor system.
 *
 *)

--module File;

--  from LessonDB import LessonDB, UserWorkSpace;
--  export FileSpace, File;

  object FileSpace is File*
    description: (*
        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.
     *);
  end;

  object File is
    components: name:FileName and permissions:FilePermissions and
        file_type:FileType and data:FileData;
    description: (*
        A File is an abstraction of a file stored in the file space.  It has a
        name, permissions, type, and data.  These are the components sufficient
        to specify the behavior of CSTutor Tool file operations.
    *);
  end File;

  object FileName is string
    description: (*
        The name of a file.  The string representation here is an abstraction
        of file names used in specific operating environments.  Implementations
        may obey any syntactic or semantic constraints imposed by a particular
        environment.
    *);
  end;

  object FilePermissions is is_readable:IsReadable and is_writable:IsWritable
    description: (*
        FilePermissions indicate whether a file is readable and/or writable.
    *);
  end;

  object IsReadable is boolean
    description: (*
        Flag indicating whether a file is readable, which is required to be
        true by the FileOpen operation.
    *);
  end;

  object IsWritable is boolean
    description: (*
        Flag indicating whether a file is writable, which is required to be
        true by the FileSave operation.
    *);
  end;

  object FileType is lesson_type:LessonType or other_type:OtherType
    description: (*
        The type of file data is either LessonType data (which we care about)
        or any other type of data that can be stored in a file, which we don't
        care about.
    *);
  end FileType;

  object LessonType
    description: (*
        File data typing tag indicating that a file contains lesson data
        created by the CSTutor Tool
    *);
  end LessonType;

  object OtherType
    description: (*
        File data typing tag indicating that a file contains data other than
        lesson data created by the CSTutor Tool
    *);
  end OtherType;

  object FileData is
    components: Lesson;
    description: (*
        The abstract representation of lesson-type FileData is a Lesson
        object.  CSTutor Tool implementors may use any concrete file data
        representation that accurately holds all Lesson components.
    *);
  end FileData;

  operation FileNew is
    inputs: uws:UserWorkSpace;
    outputs: uws':UserWorkSpace;

    description: (*
        Add a new empty Lesson to the workspace.
    *);

    precondition:
	(*

         * Before the FileNew operation can be executed, there cannot be any
         * open lessons in the Workspace.
         *)
         uws.lesson = nil;

    postcondition:
        (*

         * The output workspace has a new empty lesson.
         * the file is empty and the lesson does not require saving.
         *)
         (exists (lsn:Lesson)
            (lsn = uws'.lesson) and
            (lsn.file = nil) and
            (not lsn.requires_saving));

  end FileNew;

  operation FileOpen is
    inputs: fs:FileSpace, fn:FileName, uws:UserWorkSpace;
    outputs: fs':FileSpace, uws':UserWorkSpace;

    description: (*
        Open an existing lesson file of the given name and put the data from
        that file in the workspace.
    *);

    precondition:
        (*
         * A file of the given name exists in the given file space, the file
         * is readable, the file's data are of type lesson and there are no
         * open lessons in the workspace.
         *)
        (uws.lesson = nil) and
        (exists (file in fs)
            (file.name = fn) and
            file.permissions.is_readable and
            file.file_type?lesson_type);

    postcondition:
        (*

         * The output workspace has a new lesson containing the file data of
         * the input file, and the lesson does not require saving.
         *)
         (exists(lsn:Lesson)
            (lsn = uws'.lesson) and
            (exists (file in fs)
               (file.name = fn) and
               (lsn.file = file)
             ) and
             (not lsn.requires_saving)
          );

  end FileOpen;

  operation FileClose is
    inputs: fs:FileSpace, uws:UserWorkSpace;
    outputs: fs':FileSpace, uws':UserWorkSpace;

    description: (*
        Close the open lesson if it does not require saving.
    *);

    precondition:
        (*
         * The lesson does not require saving.
         *)
        not (uws.lesson.requires_saving);

    postcondition:
        (*
         * There are no open Lessons
         *)
         uws'.lesson = nil;

  end FileClose;

operation FileSave is
    inputs: fs:FileSpace, uws:UserWorkSpace;
    outputs: fs':FileSpace, uws':UserWorkSpace;

    description: (*
        If the lesson in the given workspace requires saving, save it in the
        given file space.
    *);

    precondition:
        (*
         * 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
         * CSTutor Tool.  Note further that this precondition disallows the
         * case where the open lesson file has been externally deleted
         * since it was opened by the CStutor tool.  That is, the file must
         * both exist and be writable at the time the save is attempted.
         *)
        (uws.lesson.requires_saving)

            and

        (exists (file in fs)
            (file.name = uws.lesson.file.name) and
            (file.permissions.is_writable));

    postcondition:
        (*
         * There is a lesson-type file in the resulting FileSpace containing
         * the open workspace lesson as its file data.  In the resulting
         * workspace, the requires saving indicator is false.
         *)
        (exists (file in fs')
            (file.name = uws'.lesson.file.name) and
            (file.permissions.is_writable) and
            (file.file_type?lesson_type) and
            (not uws'.lesson.requires_saving)
        );
  end FileSave;

--end File;