5.3. Messaging (Messaging.rsl)
(****
*
* Module Messaging defines the objects and operations related to the
various means of messaging in CSTutor. These are: Chat, Remote
* Assistance and the FAQ Board.
*
*)
object ChatRoom is
components: darea:DiscussionArea and ulist:UserList and msgarea:MessageArea and isopen:IsOpen and isVisible:IsVisible;
description: (* Chatroom contains DiscussionArea, list of users, and a message are where users type text in. *);
end ChatRoom;
object IsOpen is boolean;
object DiscussionArea is
components: publicmessagelist:PublicMessageList and systemmessagelist:SystemMessageList and whispermessagelist:WhisperMessageList;
description: (* DiscussionArea contains Public, Sytem, and Whisper Messages. *);
end DiscussionArea;
object PublicMessage is
components: UserID and string and ColorBlack;
description: (* PublicMessage contains UserID, string with the color black *);
end PublicMessage;
object SystemMessage is
components: string and ColorRed;
description: (* SystemMessage contains a string with the color red *);
end PUblicMessage;
object WhisperMessage is
components: MyUserID:UserID and OtherUserID:UserID and whpstr:WhisperString and green:ColorGreen;
description: (* contains a green whisperstring with MyUserID displayed on this user,or
with OtherUserID displayed on the other screen *);
end WhipserMessage;
object WhisperString is string;
object ColorRed is RGB;
object ColorBlack is RGB;
object ColorGreen is RGB;
object RGB;
object UserID is string;
object MessageArea is string;
object UserList is
components: UserID*;
description: (* Contains a list of userID *);
end UserList;
object PublicMessageList is
components: PublicMessage*;
description: (* contains a list of publicmessage *);
end PublicMessageList;
object SystemMessageList is
components: SystemMessage*;
description: (* contains a list of systemmessage *);
end SystemMessageList;
object WhisperMessageList is
components: WhisperMessage*;
description: (* contains a list of whispermessage *);
end WhisperMessageList;
operation SendSystemMessage is
inputs: msg:SystemMessage, disarea:DiscussionArea;
outputs: disarea':DiscussionArea;
preconditions: (* message is not null *)
msg != nil;
postcondition: (* messsage is added to the discussionArea *)
msg in disarea'.systemmessagelist;
description: (* the string in the messsageArea is being added to the DiscussionArea *);
end SendSystemMessage;
operation SendWhsprMessage is
inputs: msg:WhisperMessage, disarea:DiscussionArea;
outputs: disarea':DiscussionArea;
precondition: (* message is not null and is a valid whisper message *)
msg != nil and IsValidWhipserMessage(msg);
postcondition: (* message is added in discussionArea *)
msg in disarea'.whispermessagelist;
description: (* the string in the MessageArea must have "/w" in front to indicate
it as a whisper message and this string is added to the DiscussionArea *);
end SendWhsprMesssage;
operation SendPublicMessage is
inputs: msg:PublicMessage, disarea:DiscussionArea;
outputs: disarea':DiscussionArea;
precondition: (* message is not null *)
msg != nil;
postcondition: (* message is added in discussionArea *)
msg in disarea'.publicmessagelist;
end SendPublicMessage;
function IsValidWhipserMessage (msg:WhisperMessage) =
(* check if the message is valid as a whisper message (contains a /w in front) *)
msg.whpstr[1:2] = "/w"
end;
operation OpenChat is
input: chtrm:ChatRoom, id:UserID;
output: chtrm':ChatRoom;
precondition: (* chatroom is not open *)
(chtrm.isopen = false);
postcondition: (* UserID is addded to the chatroom user List *)
(id in chtrm'.ulist);
description: (* opens the current chat window with other users listed (if any) and add this user to the list *);
end OpenChat;
operation CloseChat is
input: chtrm:ChatRoom, id:UserID, ulist:UserList;
output: ulist':UserList, chtrm':ChatRoom;
precondition: (* chat room is currently opened *)
(chtrm.isopen = true);
postcondition: (* chatroom is closed on this user's screen and this user ID is removed from
the other's chatroom's user list (those who are still online) ulist is the user list of
everyone elses CSTutor application*)
(chtrm'.isopen = false) and (not (id in ulist'));
description: (* close the chat window *);
end CloseChat;
object IsInControl is boolean;
object UserWorkSpaceList is
components: uws:UserWorkSpace*;
description: (* contains a list of UserWorkSpace *);
end UserWorkSpaceList;
operation TakeControl is
inputs: id:UserID, my_uws:UserWorkSpace, uwsl:UserWorkSpaceList;
outputs: other_uws:UserWorkSpace;
precondition: (* I don't have control of another workspace *)
(my_uws.controlling = false);
postconditions: (* other userworkspace is opened after searched by id *)
other_uws = searchForWorkspace(id, uwsl);
description: (* Take conrol of another user workspace. id is a other user ID *);
end TakeControl;
function searchForWorkspace(id:UserID, uwsl:UserWorkSpaceList) -> uws':UserWorkSpace = (
(exists (uws in uwsl) (uws.uid = id) and (uws'= uws))
or
(uws' = nil)
)
description: (* search for a UserWorkSpace base on the input id *);
end;
operation LoseControl is
inputs: id:UserID, uwsl:UserWorkSpaceList, my_uws:UserWorkSpace;
outputs: other_uws:UserWorkSpace;
preconditions: (* I am in control of another session *)
(my_uws.controlling=true);
postconditions: (* not in control of another user and other user workspace is null on my screen *)
(my_uws.controlling=false) and (other_uws = nil) ;
description: (* Return control to other user's and have this userworkspace back *);
end LoseControl;
object FAQdb is
components: FAQ*;
description: (* contains many FAQ or none at all *);
end FAQdb;
object FAQ is
components: faqquestion:faqQuestion and answer:Answer* and date:Date and topic:Topic and keyword:Keyword*;
description: (* each FAQ contains a question, date it was posted, topic it's in, many or none answer, and many keyword
to match it when search *);
end FAQ;
object FAQList is
components: faq:FAQ*;
description: (* contains a list of FAQ *);
end FAQList;
object faqQuestion is string;
object Answer is string;
object Date is string;
object Topic is string;
object Keyword is string;
object FAQBoard is faqQuestion and searchResult;
object searchResult is
components: FAQ*;
description: (* the search result a list of FAQ*);
end searchResult;
object ViewType is UnansweredBOX or AllBOX or TopicBOX or DateBOX or KeywordBOX;
object UnansweredBOX is boolean;
object AllBOX is boolean;
object TopicBOX is boolean;
object DateBOX is boolean;
object KeywordBOX is boolean;
operation findFAQ is
inputs: faqdb:FAQdb, faqquestion:faqQuestion;
output: faql:FAQList;
precondition: (* the question is not nil *)
faqquestion != nil;
postcondition: (* FAQList is sorted *)
(forall (faq' in faql) (faq' in faqdb) and (faq'.faqquestion = faqquestion))
and
(forall (i:integer | (i >=1 ) and (i < #faql))
faql.faq[i] < faql.faq[i+1]);
description: (* find the FAQ base on the input question *);
end findFAQ;
operation sortByTopic is
inputs: faql:FAQList;
outputs: faql':FAQList;
precondition: (* faql is not nil *)
faql != nil;
postcondition: (* FAQ list is sorted by topic *)
(forall (i:integer | (i >=1) and (i <#faql))
faql.faq[1].topic < faql.faq[i+1].topic);
description: (* sort the FAQList by topic *);
end sortByTopic;
operation sortByDate is
inputs: faql:FAQList;
outputs: faql':FAQList;
precondition: (* faql is not nil*)
faql != nil;
postcondition: (* FAQ list is sorted by Date *)
(forall (i:integer | (i >=1) and (i <#faql))
faql.faq[1].date < faql.faq[i+1].date);
description: (* sort the FAQList by date *);
end sortByDate;