(**** * * Module File defines the objects and operations related to file processing * in the calendar system. * *) module File; from ScheduleDB import ScheduleDB; object UserWorkspace is components: uid:UserID and schedules:UserSchedule* and previous_state:PreviousState; description: (* This is the user workspace that contains the UserSchedule which is the current schedule that the user is working on This contains the information about what the file name is of the schedule that the user is working on and the user that is working on the file. *); end; object PreviousState is components: ScheduleDB*; description: (* This is used incase the admin does not want to save the changes that they have made to the database. This way a admin can revert back to a certain state or point in which the schedule was generated This is also helpful if the teacher creates a schedule and then doesn't like it. *); end; object UserSchedule is components: file:UserScheduleFileName* and requires_saving:RequiresSaving and uid:UserID; description: (* This contains the file that the user is working on in the given workspace. Given the user id also this tell who is working on the schedule. If there are multiple admins this could narrow down who is making the changes the schedule. *); end; object UserScheduleFileName is components: name:FileName; description: (* This is the file name of schedule being accessed is the User workspace. *); end; object RequiresSaving is boolean description: (* This tell if the schedule has been modified so that if the user goes to close the schedule without having saved yet, the program will prompt the user to save the schedule. That way no changes are made that get left out becuase the user left the program without saving. *); end; object UserID is integer description: (* This defines the UserID that is working on the schedules currently in the program. *); end; object FileSpace = 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 components: name:FileName and permissions:FilePermissions and file_type:FileType and size:FileSize 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 Schedule Tool file operations. *); end File; object FileName = 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_readable:IsReadable and is_writable:IsWritable description: (* FilePermissions indicate whether a file is readable and/or writable. *); end; object IsReadable = boolean description: (* Flag indicating whether a file is readable, which is required to be true by the FileOpen operation. *); end; object IsWritable = boolean description: (* Flag indicating whether a file is writable, which is required to be true by the FileSave operation. *); end; object FileType = schedule_type:ScheduleType description: (* The type of file data is either CalendarType data (which we care about), SettingsType data (which we also care about), or any other type of data (which we don't care about). *); end FileType; object ScheduleType is boolean description: (* This tell if the program can open the type of file. If the type of file is not a Schedule then the program will not be able to read the file correctly and display the correct information about the databases. This way the program will not open xcel or word files and try to create a database off of bad information. *); end; object CalendarType description: (* File data typing tag indicating that a file contains calendar data created by the Calendar Tool. *); end CalendarType; object FileSize = integer description: (* The size in megabytes of a file. *); end FileSize; object FileData = UserSchedule description: (* The abstract representation of schedule-type FileData is a UserSchedule object. Schedule Tool implementors may use any concrete file data representation that accurately holds all UserSchedule components. *); end FileData; obj Quarter is string description: (* This is sed to define in the name of the schedule what quarter the schedule is for. *); end; obj Year is integer description: (* This is used to define in the name of the schedule what year the schedule is for. *); end; obj Revision = integer; operation FileNewFromScratch inputs: Quarter and Year and Revision and fs:FileSpace and fn:FileName and uws:UserWorkspace; outputs: uws':UserWorkspace; precondition: not ( exists (file in fs) (file.name = fn) ); postcondition: (exists (uc:UserSchedule) (uc = uws'.schedules[1]) and (exists (file in fs) (file.name = fn) and (uc = file.data) ) and (uc.uid = uws.uid) and (not uc.requires_saving) and (#(uws'.schedules) = #(uws.schedules) +1) and (forall (i:integer | (i >= 2) and (i <= #(uws.schedules))) uws'.schedules[i+1] = uws.schedules[i+1] ) ); description: (* * This takes in the name of what the new schedule is to be called and creates a schedule * with temp databases layout allowing the user to add entries into the temp database. *); end FileNewFromScratch; operation FileOpen inputs: fs:FileSpace and fn:FileName and uws:UserWorkspace; outputs: uws':UserWorkspace; precondition: 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. *) (exists (uc:UserSchedule) (uc = uws'.schedules[1]) and (exists (file in fs) (file.name = fn) and (uc = file.data) ) and (uc.uid = uws.uid) and (not uc.requires_saving) and (#(uws'.schedules) = #(uws.schedules) +1) and (forall (i:integer | (i >= 2) and (i <= #(uws.schedules))) uws'.schedules[i+1] = uws.schedules[i+1] ) ); description: (*File Open opens a file from disk and populates all windows with the correct data*); end FileOpen; operation FileClose inputs: fs:FileSpace, uws:UserWorkspace; outputs: uws':UserWorkspace; precondition: (*The schedule does not require saving.*) not (uws.schedules[1].requires_saving); 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 (uws.schedules[1] in uws'.schedules)) and (#(uws'.schedules) = #(uws.schedules) - 1) and (forall (i:integer | (i >= 1) and (i < #(uws.schedules))) uws'.schedules[i] = uws.schedules[i+1]; ); description: (* Close the current schedule if it does not require saving *); end FileClose; operation FileSave inputs: fs:FileSpace, uws:UserWorkspace; outputs: fs':FileSpace, uws':UserWorkspace; 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 * Schedule Tool. Note further that this precondition disallows the * case where the current schedule file has been externally deleted * since it was opened by the schedule tool. That is, the file must * both exist and be writable at the time the save is attempted. *) (uws.schedules[1].requires_saving) and (exists (file in fs) (file.name = uws.schedules[1].file[1].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 is false. *) (exists (file in fs') (file.name = uws'.schedules[1].file[1].name) and (file.data = uws'.schedules[1]) and (file.permissions.is_writable) and (file.file_type.schedule_type) and (not uws'.schedules[1].requires_saving) ); end FileSave; end File;