(**** * * Module File defines the objects and operations related to file processing * in the Scheduler Tool. * *) module File; from Databases import ScheduleDB, ScheduleRecord, CourseDB, InstructorDB, InstructorCoursePreferenceDB, InstructorTimePreferenceDB, ClassroomDB; from Edit import Clipboard, Selection, SelectionContext; from Admin import AdminDB, Server, Username; export FileSpace, File, WorkspaceContainer, Workspace, WSTitle, PreviousState, RequiresSaving; object FileSpace is File* description: (* A FileSpace is an abstract model of a file space in the operating environment in which the SchedulerTool 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 Scheduler 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 schedule_type:ScheduleType or other_type:OtherType description: (* The type of file data is either ScheduleType 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 ScheduleType description: (* File data typing tag indicating that a file contains schedule data created by the Schedule Tool *); end ScheduleType; object OtherType description: (* File data typing tag indicating that a file contains data other than schedule data created by the Scheduler Tool *); end OtherType; object FileData is Workspace description: (* The abstract representation of schedule-type FileData is a Scheduler object. Scheduler Tool implementors may use any concrete file data representation that accurately holds all Scheduler components. *); end FileData; object WorkspaceContainer is components: uws:Workspace*; description: (* The WorkspaceContainer contains the active schedules upon which the user is working. The Workspace* component is the list of active schedules; the list is maintained in the order visited by the user, with the first element being the most recently visited, and hence current, and the last element being the earliest visited. *); end WorkspaceContainer; object Workspace is components: title:WSTitle and scdb:ScheduleDB and CourseDB and ClassroomDB and InstructorDB and InstructorCoursePreferenceDB and InstructorTimePreferenceDB and rs:RequiresSaving and is_master:boolean and Server and AdminDB and previous_state:PreviousState and file:File and uid:Username and clipboard:Clipboard and selection:Selection and context:SelectionContext; description: (* A workspace contains all the information which is specific to a certain quarter's schedule *); end Workspace; object WSTitle is string; object PreviousState is components: ScheduleRecord*; description: (* PreviousState is the snapshot of scheduled items before the most recently performed scheduling operation used by EditUndo. The schedule edit operations and update schedule operation save the previous state to support Undo. *); end PreviousState; object RequiresSaving is boolean description: (* True if a calendar requires saving, which is the case if one or more successful edit operations has been performed on the calendar since the most recent save. The calendar edit operations are Schedule, Change, and Delete. *); end RequiresSaving; operation FileNew is inputs: wsc:WorkspaceContainer; outputs: wsc':WorkspaceContainer; description: (* Add a new empty schedule to the WorkspaceContainer and make it current. *); precondition: ; postcondition: (* * The output workspace has a new empty schedule and that schedule is * current. The schedule does not require saving. The schedules in * positions 1-last in the the input workspace are in positions * 2-last+1 in the output workspace. *) (exists (uws:Workspace) (uws = wsc'.uws[1]) and (uws.file = nil) and (not uws.rs) and (#(wsc'.uws) = #(wsc.uws) +1) and (forall (i:integer | (i >= 2) and (i <= #(wsc.uws))) wsc'.uws[i+1] = wsc.uws[i+1] ) ); end FileNew; operation FileOpen is inputs: fs:FileSpace, fn:FileName, uws:Workspace; outputs: fs':FileSpace, uws':Workspace; description: (* Open an existing schedule 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, and the file's data are of type schedule. *) exists (file in fs) (file.name = fn) and file.permissions.is_readable and file.file_type?schedule_type; postcondition: (* * The output workspace has a new schedule containing the file data of * the input file, and that schedule is current. The user id of the * new schedule is that of the workspace, the options are the given * global options input, and the schedule does not require saving. The * schedules in positions 1-last in the the input workspace are in * positions 2-last+1 in the output workspace. *); end FileOpen; operation FileClose is inputs: fs:FileSpace, uws:Workspace, rs:RequiresSaving, wsc:WorkspaceContainer; outputs: fs':FileSpace, uws':Workspace, wsc':WorkspaceContainer; description: (* * Close the current schedule if it does not require saving. *); precondition: (* * The schedule does not require saving. *) not (uws.rs); postcondition: (* * The current schedule is deleted from the workspace. The remaining * schedules, if any, are shifted in position in the list one position * earlier. *) (not (wsc.uws[1] in wsc'.uws)) and (#(wsc'.uws) = #(wsc.uws) - 1) and (forall (i:integer | (i >= 1) and (i < #(wsc.uws))) wsc'.uws[i] = wsc.uws[i+1]); end FileClose; operation FileSave is inputs: fs:FileSpace, uws:Workspace, wsc:WorkspaceContainer; outputs: fs':FileSpace, uws':Workspace, wsc':WorkspaceContainer; description: (* If the schedule 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 * Scheduler Tool. Note further that this precondition disallows the * case where the current schedule file has been externally deleted * since it was opened by the scheduler tool. That is, the file must * both exist and be writable at the time the save is attempted. *) (uws.rs) and (exists (file in fs) (file.name = wsc.uws[1].file.name) and (file.permissions.is_writable)); postcondition: (* * There is a schedule-type file in the resulting FileSpace containing * the current workspace schedule as its file data. In the resulting * workspace, the requires saving indicator and is false. *) (exists (file in fs') (file.name = wsc'.uws[1].file.name) and (file.permissions.is_writable) and (file.file_type?schedule_type) and (not wsc'.uws[1].rs) ); end FileSave; end File;