5.1. File Menu (file.rsl)
(* Chris Noe *)
(* describe file formats *)
module File;
from Edit import UserWorkSpace;
from Question import QuestionDB;
from Test import Test;
export FileSpace, File, RequiresSaving, FileType, TakenTestType, GradedTestType;
object FileSpace is File*
description: (*
A FileSpace is an abstract model of a file space in the operating
environment in which the TestTool 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 Question 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 test_type:TestType or taken_test_type:TakenTestType or graded_test_type:GradedTestType or other_type:OtherType
description: (*
The type of file data is either TestType 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 TestType
description: (*
File data typing tag indicating that a file contains test data
created by the Question Tool.
*);
end TestType;
object TakenTestType
description: (*
File data typing tag indicating that a file contains taken test data
created by the Question Tool.
*);
end TakenTestType;
object GradedTestType
description: (*
File data typing tag indicating that a file contains graded test data
created by the Question Tool.
*);
end GradedTestType;
object OtherType
description: (*
File data typing tag indicating that a file contains data other than
test data created by the Question Tool.
*);
end OtherType;
object FileData is Test
description: (*
The abstract representation of test-type FileData is a Test
object. Question Tool implementors may use any concrete file data
representation that accurately holds all Test components.
*);
end FileData;
object RequiresSaving is boolean
description: (*
True if a test requires saving, which is the case if one or more
successful edit operations has been performed since the
most recent save.
*);
end RequiresSaving;
operation FileNew is
inputs: uws:UserWorkSpace;
outputs: uws':UserWorkSpace;
description: (*
Add a new empty test to the workspace and make it current.
*);
precondition: (* none *);
postcondition:
(*
* The output workspace has a new empty test and that test is
* current. We are using a single document model, so the logic
* here is fairly simple.
*)
(exists (test:Test)
(test = uws'.test) and
(not test.requires_saving)
);
end FileNew;
operation FileOpen is
inputs: fs:FileSpace, fn:FileName, uws:UserWorkSpace;
outputs: uws':UserWorkSpace;
description: (*
Open an existing test 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 test.
*)
exists (file in fs)
(file.name = fn) and
file.permissions.is_readable and
file.file_type?test_type;
postcondition:
(*
* The output workspace has a new test containing the file data of
* the input file. We are using a single document model.
*)
(exists (test:Test)
(test = uws'.test) and
(exists (file in fs)
(file.name = fn) and
(test = file.data)
) and
(not test.requires_saving)
);
end FileOpen;
operation FileClose is
inputs: fs:FileSpace, uws:UserWorkSpace;
outputs: uws':UserWorkSpace;
description: (*
Close the current test if it does not require saving.
*);
precondition:
(*
* The test does not require saving.
*)
not (uws.test.requires_saving);
postcondition:
(*
* The current test is deleted from the workspace.
*)
(uws.test = nil);
end FileClose;
operation FileSave is
inputs: fs:FileSpace, uws:UserWorkSpace;
outputs: fs':FileSpace, uws':UserWorkSpace;
description: (*
If the test 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
* Question Tool. Note further that this precondition disallows the
* case where the current test file has been externally deleted
* since it was opened by the test tool. That is, the file must
* both exist and be writable at the time the save is attempted.
*)
(uws.test.requires_saving)
and
(exists (file in fs)
(file.name = uws.test.file.name) and
(file.permissions.is_writable));
postcondition:
(*
* There is a test-type file in the resulting FileSpace containing
* the current workspace test as its file data. In the resulting
* workspace, the requires saving indicator is false.
*)
(exists (file in fs')
(file.name = uws'.test.file.name) and
(file.data = uws'.test) and
(file.permissions.is_writable) and
(file.file_type?test_type) and
(not uws'.test.requires_saving)
);
end FileSave;
end File;
Prev: none
| Next: edit.rsl
| Up: formal specification
| Top: index