(**** * * Module tutorial defines the objects and operations related to roadmapping * and posting a tutorial in the CSTutor. * *) module tutorial; from Page import Page, Thumbnail; from Data import all; from Login import all; export all; object Tutorial is components: title:Title and pages:Page* and pageNames:PageName* and roadmap:Roadmap; operations: AddPage, RemovePage, PostTutorialStep1, DisplayRoadmap; description: (* A tutorial is the compilation of pages. The instructor can add pages that he or she has made from scratch or download them from the CSTutor online Pages Database. He or she can also remove these added pages. The pages are added in sequential order. An instructor can post the completed tutorial to the internet. *); end Tutorial; object Title is string; (* The title in the title bar of the window *) object PageName is string; (* This PageName should = the Page.Name of the page in question *) object Roadmap is components: title:Title and thumbnails:Thumbnail* and thumbnailNames:ThumbnailName*; description: (* A roadmap is the exact graphical representation of a tutorial; *); end Roadmap; object ThumbnailName is string; (* This is the exact name of the page that the thumbnail in question reprersents *) operation AddPage is inputs: pagesDB:PageDB, tutorial:Tutorial, page:Page; outputs: tutorial':Tutorial; description: (* The Instructor selects a Page from the PagesDB and then adds it to the Tutorial. The Tutorial is hence updated with the new Page and output. *); precondition: (* * A page must be selected to add *) page != nil; postcondition: (* * The page added must be added to the end of the tutorial. *) page = tutorial'.pages[#tutorial.pages + 1] and (* * All the pages in the original tutorial still exist in their proper order before the just added page. *) (forall (i:integer | (i >= 1) and (i < #tutorial'.pages)) tutorial.pages[i] = tutorial'.pages[i]); end AddPage; operation RemovePage is inputs: tutorial:Tutorial, pages:Page*; outputs: tutorial':Tutorial; description: (* Instructor selects Pages in the Tutorial to remove. The tutorial is hence updated without having the selected pages. *); precondition: (* * A page or pages are selected to be removed and exists in the tutorial *) (forall (i:integer | (i >= 1) and (i <= #pages)) (pages[i] != nil) and (pages[i] in tutorial.pages)); postcondition: (* * The page or pages selected to be removed is no longer in the tutorial *) (forall (k:integer | (k >= 1) and (k < #pages)) (forall (i:integer | (i >= 1) and (i < #tutorial'.pages)) tutorial'.pages[i] != pages[k])) and (* * The number of pages is decreased by the number of pages remove *) #tutorial'.pages = (#tutorial.pages - #pages); end RemovePage; operation PostTutorialStep1 is inputs: step1Complete:Step1Complete and step1Input:Step1Input; outputs: step1Output:Step1Output and step1Complete':Step1Complete; description: (* PostTutorialStep1 firsts opens a Log In dialog and sends that completed info out to the next step of posting. *); precondition: (* * Step1 must not be completed yet. *) step1Complete = false; postcondition: (* * step1Output must be filled with valid data *) step1Output.loginCookie'.userID != nil and step1Output.loginCookie'.isAuthenticated = true and (* * Step1 must be completed. *) step1Complete = true; end PostTutorial; Step1Complete is boolean; (* Indicated what part of the wizard has been completed *) object Step1Input is components: loginCookie:LoginCookie; description: (* Retrieves information about where to post tutorials. *); end Step1Input; object Step1Output is components: loginCookie':LoginCookie; description: (* This is filled login info *); end Step1Input; operation PostTutorialStep2 is inputs: step1Complete:Step1Complete, step2Input:Step2Input; outputs: step2Output:Step2Output; description: (* PostTutorialStep2 takes the valid information handed back from the Log In dialog and now gets the information that is needed as to what needs to be posted and for whom. *); precondition: (* * Step1 must be completed. *) step1Complete = true and (* * There must be an active internet connection *) step2Input.activeInternet = true and (* * Step2Input must be valid. *) step2Input.postInfo.currentD != nil and step2Input.postInfo.tutorial != nil and step2Input.postInfo.assignedClass != nil; postcondition: (* * The tutorial must be posted by having it not equal the old database and it actually being in there. *) step2Output.tutorialDB != step2Input.tutorialDB and (exists (i:integer | (i >= 1) and (i <= #step2Output.tutorialDB)) (step2Output.tutorialDB[i].tutorial = step2Input.postInfo.tutorial)); end PostTutorialStep2; object Step2Input is components: postInfo:PostInfo, loginInfo:LoginCookie, tutorialDB:TutorialDB, activeInternet:ActiveInternet; description: (* PostTutorial firsts gets the LoginInfo from the instructor and gets all the PostInfo to make the proper post to the CSTutor database. *); end Step2Input; object PostInfo is components: currentD:CurrentDirectory and tutorial:Tutorial and assignedClass:AssignedClass; description: (* The Post Info is the Tutorial the instructor selects to post along with what directory it is in. Lastly the specific class it is assigned to. *); end PostInfo; object CurrentDirectory is string; (* The default name of the folder the user is browsing *) object AssignedClass is string; (* These are gathered when the user signs in and retrieves the account information from the server. *) object ActiveInternet is boolean; (* Indicates wheather the internet is active or not by means of network testing *) object Step2Output is components: postSuccessful:PostSuccessfulMessage and tutorialDB:TutorialDB; description: (* The tutorial posted information. *); end Step2Output; object PostSuccessfulMessage is string; (* "Successful Post" message displays a message in the following format: "Thank you What ever Teacher Name was signed in, what ever tutorial selected in the "Post Info" dialog has been posted for your following class: What ever class was choosen in the "Assigned Class" combo box." *) operation DisplayRoadmap is inputs: roadmap:Roadmap, tutorial:Tutorial; outputs: roadmap':Roadmap; precondition: (* * The title of the roadmap does not equal the title of the tutorial *) roadmap.title != tutorial.title or (* * The number of thumbnails in the roadmap does not equal the number of pages in the tutorial *) #roadmap.thumbnails != #tutorial.pages or (* * All the thumbnail names do not match the page names in order since they should be identical *) (exists (i:integer | (i >= 1) and (i <= #tutorial.pages)) (tutorial.pages[i] != nil) and (tutorial.pageNames[i] != roadmap.thumbnailNames[i])); postcondition: (* * The title of the roadmap does equal the title of the tutorial *) roadmap.title = tutorial.title and (* * The number of thumbnails in the roadmap equals the number of pages in the tutorial *) #roadmap'.thumbnails = #tutorial.pages and (* * All the thumbnail names match the page names in order since they should be identical *) (exists (i:integer | (i >= 1) and (i <= #tutorial.pages)) (tutorial.pages[i] != nil) and (tutorial.pageNames[i] = roadmap.thumbnailNames[i])); end DisplayRoadmap; end tutorial;