Fredrik Claesson
Magnus Jakobsson
Andreas Johansson
Per Lindh
Björn Löndahl
Erik Malm
Innehåll
Inledning
*Allmänna designbeslut
*1 Klassdiagram
*2 Klasser
*2.1 TLetter (Brev)
*2.1.1 Metoder
*2.1.2 Attribut
*2.2 THeader (Header)
*2.2.1 Metoder
*2.2.2 Attribut
*2.3 TAddress (Adress)
*2.3.1 Metoder
*2.3.2 Attribut
*2.4 TRawData
*2.4.1 Metoder
*2.4.2 Attribut
*2.5 TFolder (Mapp)
*2.5.1 Metoder
*2.5.2 Attribut
*2.5.3 Undantag
*2.6 TPostOffice (Postkontor)
*2.6.1 Metoder
*2.6.2 Attribut
*2.6.3 Undantag
*2.7 TCodeManager (Kodningshanterare)
*2.7.1 Metoder
*2.7.2 Attribut
*2.8 TMailBox (Brevlåda)
*2.8.1 Metoder
*2.8.2 Attribut
*2.9 TSendModule
*2.9.1 Metoder
*2.9.2 Attribut
*2.10 TRecieveModule
*2.10.1 Metoder
*2.10.2 Attribut
*2.11 TIO (Fil IO)
*2.11.1 Metoder
*2.11.2 Attribut
*2.12 TMMap
*2.12.1 Metoder
*2.12.2 Attribut
*3 Scenarion
*3.1 Skicka brev
*3.2 Ta emot brev
*3.3 Skriva brev
*3.4 Editera brev
*3.5 Visa brev
*4 Grafiskt gränssnitt (GUI)
*Denna designspecifikation ingår i projektkursen Objektorienterad utveckling av användbara system vid Linköpings Tekniska Högskola.
Designen beskriver en mailklient för Windows 95/NT4.
Vi har valt att utveckla applikationen i Microsoft Visual C++ (VC++). Detta är en utvecklingsmiljö som är mycket vanlig i PC-sammanhang. Den är modern och har många intressanta finesser, liksom rätt hög inlärningströskel.
En av delarna i VC++ är Microsoft Foundation Classes (MFC), som är ett mycket stortklassbibliotek, med allt ifrån strängklasser till klasser för att hämta websidor. Vi har valt att i så stor utsträckning som möjligt använda MFC, i synnerhet vad gäller det grafiska användargränssnittet.
Användningen av MFC gör att programstart och dylikt inte riktigt går till som det brukar i vanliga program, med en main()-funktion som anropas vid uppstart. Istället används s.k. applikationsobjekt ärvda från MFC-klassen CApplication. Vi har av denna anledning valt att ej närmare specificera programstart i designen, då det helt och hållet beror på implementationen av CApplicationklassen.
Klassdiagrammet på nästa sida är konstruerat så att klassbenämningarna från analysen står kvar. Klassnamnen är dock på engelska, och den motsvarande analysbenämningen har givits inom parenteser i rubrikerna för respektive klass.
Klassdiagram
TLetter
(long int ID, Theader& header) Extern funktionKonstruktor som används av TIO objektet
TLetter(TRawData& rawData) Extern funktion
Används av TMailBox då nytt mail kommer in.
Anropar codeManager.DecodeHeader(rawData) för att få headern.
TLetter(THeader& header, CString& s) Interfacefunktion
Används av GUI för att skapa ett nytt brev.
Anropar codeManager.EncodeLetter(s, header) för att få rådatan.
void SetFolderID(long int ID) Extern funktion
long int GetFolderID() Extern funktion
Cstring& GetReadableText() Interfacefunktion
Returnerar codeManager.DecodeRawData(rawData)
THeader& GetHeader() Interfacefunktion
TRawData& GetRawData() Extern funktion
void Save() Extern funktion
anropar TIO.SaveLetter(this)
CString& GetBlaBlaBla() Interfacefunktion
anropar codeManager.GetBlaBlaBla(rawData)
void Delete() Interfacefunktion
anropar TIO.DeleteLetter(this)
void SaveAttachment(TAttachment attachment, CString filename) Interfacefunktion
anropar TIO.SaveAttachment(attachment, filename)
TFolder&
folder PrivatReferens till förälderfoldern.
TRawData& rawData Privat
Innehåller brevets smtp-kodade del, som kan skickas.
THeader& header Privat
Brevets header (dvs till, från osv )
THeader(
CString& to, CString& from, Cstring& CC, Cstring& subject, int flags)void SetFlags(int flags) Interfacefunktion
Där flags ges som en or-kombination av flaggkonstanterna (se nedan)
void ClearFlags(int flags) Interfacefunktion
bool GetFlag(int flag) Interfacefunktion
Returnerar sant/falskt beroende på hur den aktuella flaggan är satt
CList <TAddress> GetTo() Interfacefunktion
CList <TAddress> GetCC() Interfacefunktion
TAddress& GetFrom() Interfacefunktion
CString& GetSubject() Interfacefunktion
CList <TAdress>
to PrivatCList <TAddress> CC Privat
CString from Privat
CString subject Privat
int flags Privat
Där flags är en enum:
read = 0x00000001
sent = 0x00000002
replied = 0x00000004
changed = 0x00000008
external = 0x00000010
locked = 0x00000020
TAddress(
CString address, CString name) InterfacefunktionCString& GetAddress() Interfacefunktion
CString& GetName() Interfacefunktion
CString
address privatCString name privat
Kapslar in minneshanteringen av brevets rådata. Antingen används
Memory Mapped IO (MMap) eller så används en vanlig minnespekare.
Pseudokod:
TRawData
{
char* mem (privat)
MMap* mmap (privat) (=NULL innebär att char* pekar till minne)
long size (privat)
TRawData(CString* s);
TRawData(TMMap* mmap);
~TRawData {om mmap avmappa mmap annars gör delete på mem };
long GetSize( );
char* GetMem( );
}
TRawData
(CString* s) Extern funktionSkapar ett rådataobjekt som enbart existerar som en sträng i minnet. Sätter mem till s och mmap till NULL.
TRawData(TMMap* m) Extern funktion
Skapar ett rådataobjekt som är minnesmappat. Sätter mem till
mmap->pointer och mmap till m.
~TRawData( ) Extern funktion
Destruktor.
Om MMap används d v s om mmap ¹ NULL så ska mmap avmappas. Annars ska mem tas bort.
long GetSize( ) Extern funktion
Tar ut längden på rådatafilen eller rådatasträngen.
char* GetMem( ) Extern funktion
Tar fram pekaren till rådatafilen.
char
* mem PrivatPekare till rådatafil i minnet.
TMMap* mmap Privat
Pekare till ett TMMap-objekt. Om mmap = NULL betyder det att det är char* mem som pekar till minnet där rådatan ligger.
long size Privat
Längden på en rådatafil.
TFolder är den klass som hanterar mappsystemet i mailklienten.
MetoderTFolder
(CString name, long int=NO_ID) Extern funktionOm inget ID är angivet sätts rotmappen som förälder, och TIO frågas om ett unikt ID.
void Save() Intern funktion
Sparar mappen och dess innehåll enligt följande pseudokod:
for
each letter l doif l is modified
l.Save()
for each subfolder f do
if f is modified
f.Save()
void Rename(CString name) Interfacefunktion
Rename ändrar inte på disken. Save måste anropas för att ändringarna skall bli permanenta.
void ChangeParent(TFolder& parent) Intern funktion
Ändrar förälder på mappen. Förändringen slår igenom i filstrukturen direkt genom att TIO::MoveFolder() anropas.
void AddLetter(TLetter& l) Extern funktion
void RemoveLetter(TLetter& l) Intern funktion
Ta bort ett brev ur mappen. Om brevet ej existerar genereras undantaget ELetterNotInFolder. Brevets folder sätts till NULL.
void AddSubfolder(TFolder& f) Extern funktion
void LoadLetters() Intern funktion
Laddar in samtliga brev i mappen om inte flaggan lettersloaded är satt (varvid detta redan utförts). Inladdningen sker genom att anropa TIO::LoadHeaders(this).
CList<TLetter> GetLetters() Interfacefunktion
Utför
if
not lettersloadedLoadLetters()
return letters
void Delete() Extern funktion
Tar bort mappen och allt dess innehåll från disk. Därefter kan programmeraren göra delete f där f är den aktuella foldern. Delete exekveras enligt följande algoritm:
for
all subfolders s dos.Delete()
for all letters l do
l.Delete()
TIO::DeleteFolder(this)
TFolder& GetParent() Interfacefunktion
Åtkomstfunktion för att komma åt föräldern.
CList<TFolder> GetSubFolders() Interfacefunktion
Åtkomstfunktion för att få lista på undermappar.
void RemoveSubfolder(TFolder& f) Extern funktion
Tar bort subfolder f från listan över undermappar. Den tidigare underfolderns förälderID sätts till NO_ID.
long int
folderID PrivatFolderns unika ID-nummer.
TFolder& parent Publik
Referens till förälderfoldern.
long int flags Privat
Flaggor för foldern. Flaggor anges enligt en konstantstruktur, flag-enum enligt:
enum flag-enum
{
modified=0x0001,
lettersloaded=0x0002
};
CList<TFolder>
folders PrivatLista över alla undermappar.
CList<TLetter> letters Privat
Lista över alla brev i mappen.
CString name Publik
Mappens namn. Används enbart av GUIn för att presentera mappen lite trevligare än med ett nummer.
ELetterHasParent
Undantag som genereras då ett brev som redan tillhör en folder skickas som argument till AddLetter.
ELetterNotInFolder
Undantag som genereras då RemoveLetter anropas med ett brev som inte ligger i den aktuella mappen.
EAlreadyInFolder
Genereras då en folder redan innehåller den folder som skickas som argument till AddSubFolder.
En global variabel som hanterar alla in/utgående brev. Härifrån initieras stora delar av programmet genom att rotmappen laddas och flera huvudobjekt skapas.
Metodervoid Initialize( ) Interfacefunktion
Laddar in rotmappen och skapar vissa huvudobjekt.
void LoadRootFolder( ) Intern funktion
Laddar in rotmappen m h a TIO.
void DeleteLetter(TLetter &l) Interfacefunktion
Tar bort ett brev.
void DeleteFolder(TFolder &f) Interfacefunktion
Tar bort en mapp.
TFolder& FindFolder(int ID) Interfacefunktion
Använder TIO för att ta fram en mapp.
TFolder& GetRootFolder ( ) Interfacefunktion
Tar fram rotmappen.
void PlaceLetter(TLetter l, TFolder f=OutBox) Interfacefunktion
Lägger in ett brev i en mapp som kan anges. Om en mapp
inte anges läggs brevet i OutBox.
mailBox.PrepareToSend( )
void PlaceFolder(TFolder f1, TFolder f2) Interfacefunktion
Flyttar alternativt lägger in en mapp i en annan.
void ReceiveLetters(CList<TLetter> l) Extern funktion
Tar emot en lista av brev och lägger in dessa i rätt mapp beroende på statusflaggor i breven. Låter sedan RuleManager applicerar regler på var och ett av breven.
gör för varje brev PlaceLetter(TLetter l, "ev. InBox/SentMail")
CList<TLetter> ListOutgoingMail( ) Extern funktion
Tar fram de brev som ska skickas och tar bort dem från OutBox.
TRuleManager& GetRuleManager( ) Interfacefunktion
Tar fram en referens till TRuleManager.
TCodeManager& GetCodeManager( ) Interfacefunktion
Tar fram en referens till TCodeManager.
TMailBox
mailBox PublikBrevlådan som tar emot och skickar breven.
TIO TIO Publik
Gränssnittet mot filsystemet.
TCodeManager codeManager Publik
Kodar/avkodar brev till/från olika format.
TRuleManager ruleManager Publik
Applicerar regler på brev. Ej minimal ambitionsnivå!
TFolder rootFolder, outBox, inBox, sentMail, trash Publik
Fördefinierade mappar. Konstanter i objektet.
enum
{ rootID=0,
outBoxID=1,
inBoxID=2,
sentMailID=3,
trashID=4
}
EIOLoadFolderError
Då TIO misslyckas med att ladda en map.EPlaceFolderError Då en mapp inte blivit flyttad som begärt.
EInvalidIDError Då ett ID inte på något sätt är felaktigt.
Syftet är att hantera kodning och avkodning av ett brev. Kodningen sker av brev som användaren har skrivit och som han/hon sedan vill skicka eller spara. Avkodning sker då ett brev ska läsas/editeras. Då ett brev ska avkodas tas först headern fram och sedan själva brevtexten.
MetoderCString DecodeLetter(TRawData& r) Extern funktion
Tar ut själva brevtexten.
THeader DecodHeader(TRawData& r) Extern funktion
Avkodar headern och tar ut den information som ska presenteras.
Anropar r.GetBlaBlaBla(TRawData& r)
Tar ut de intressanta fälten (To, From, CC, Subject)
CString& GetBlaBlaBla(TRawData& r) Extern funktion
Tar ut BlaBlaBla
CString& EncodeLetter(CString l, Theader h) Extern funktion
Kodar ett skrivet brev till ett format som används då brevet ska skickas.
Genererar header i SMTP-format, samt slår ihop header och text.
char* GetAttachment(TAttachment t, TRawData r) Extern funktion
(Ej minimal ambitionsnivå)
List of TEncoder
encoder PrivatKodare för att koda skrivet brev till sändbart brev.
List of TDecoder decoder Privat
Avkodare för att ta fram texten till ett brev som ska läsas eller editeras.
Klassen TMailBox hanterar all nätverkskommunikation. Den huserar i en egen tråd för att ej störa resten av applikationen när mail hämtas och lämnas. Kommunikationen mellan tråden och resten av systemet görs med hjälp av normala meddelandesändningar alternativt delat minne i kombination med semaforer. Valet beror på vad som visar sig enklast att genomföra i VC++.
MetoderTMailBox
() intern funktionSkapar en ny tråd. Sätter en timer som meddelar när kontroll av ny post ska göras.Väntar sedan på antingen en timer eller på att postkontorer gör PrepareToSend()
void PrepareToSend() extern funktion
Initiera en uppkoppling för att skicka brev. Eftersom TMailBox ligger i en annan tråd görs denna funktion med hjälp av meddelandesändning.
TReceiveModule
in;TSendModule out;
void Connect() extern funktion
Kopplar upp förbindelsen med mailservern och returnerar när uppkopplingen lyckas.
void Send(TLetter &) extern funktion
Skickar ett brev och stänger sedan INTE förbindelsen. Påverkar ej brevets flaggor. Förutsätter att brevet gick att skicka.
void Close() extern funktion
Stänger förbindelsen med mailservern.
CString
hostnamebool Check()
Kontrollerar om det finns brev att hämta. Returnerar sant så är fallet.
TRawData &Recieve()
Tar emot ett brev och ger rådata med data lagrad i minnet tillbaka.
CString
hostname, username, passwordTIO
() intern funktionInitierar nextAvailID till största värdet av breven på disk + 1
Initerar folderIDTab så att den är tom.
TFolder& LoadFolder(long int folderID) extern funktion
Laddar in alla mappar men inte de brev som ligger i dessa.
Anropas endast vid initiering.
Använder: TFolder::TFolder(long int, CString)
LoadFolder(ID) (rekursivt)
TFolder::AddFolder(TFolder &)
TFolder::SetParent(TFolder &)
void LoadHeaders(TFolder &) extern funktion
Laddar in brevobjekten från fil i viss folder, ej rekursivt
Breven minnesmappas in i adressrymden med hjälp av TMMapobjekt.
Använder
TLetter::TLetter(ID, TRawData &)
TFolder::AddLetter(TLetter &)
TLetter::SetParent(TFolder &)
void SaveLetter(TLetter &) extern funktion
Sparar ett brev med det givna IDt. Om brevet saknar ID tilldelas den ett nytt. Om brevet redan är sparat skrivs det över.
void SaveFolder(TFolder &) extern funktion
Sparar en mapp med det givna IDt. Om mappen saknar ID tilldelas den ett nytt. Om mappen redan är sparad skrivs det över men breven ligger kvar.
void DeleteLetter(TLetter &) extern funktion
Tar bort ett brev från hårddisken och sätter ID till NOID. Därefter är det upp till programmeraren att göra delete på brevobjektet.
void DeleteFolder(TLetter &) extern funktion
Tar bort en mapp från hårddisken och sätter ID till NOID. Förutsätter att mappen är tom - genererar EFolderNotEmpty om så inte är fallet. Därefter är det upp till programmeraren att göra delete på mappobjektet.
void SaveAttachment(TAttachment &, CString filename) extern funktion
Sparar ner ett binärt attachment på disk under givet filnamn.
TFolder &FindFolder(long int id) extern funktion
Ger en referens till mappobjektet med givet ID.
TLetter &FindLetter(long int id) extern funktion
Ger en referens till brevobjektet med givet ID.
TID
nextAvailIDContainer folderIDTab {Mappning av ID till objekt}
TMMap
(CString filename, int readwrite, int size) extern funktionInitierar objektet så att minnesmappningen pekar på en fil. Offseten sätt till 0. Om inte filen existerar så kommer en fil med angiven storlek att skapas.
~TTMap() extern funktion
Stänger filen och tar bort minnesmappningen
char &operator[](int i) extern funktion
Överlagra arrayindex operatorn så att objektet verkar vara en teckenarray.
SetOffset(int) extern funktion
Ställer var någonstans i filen som minnesmappningen ska börja.
CString
filename;Interna strukturer för filhantag (hFile) och minnemappning (hMap);
char *pointer;
Om användaren istället trycker på Spara eller Avbryt blir punkt 5 postOffice.PlaceLetter(letter, "Annan folder"). Om Avbryt väljs och användaren inte vill spara det han gjort skapas aldrig något brevobjekt.
Det grafiska gränssnittet kommer att ha ett ungefärligt utseende enligt nedanstående skärmdump. Skärmdumpen kommer från en tidig prototyp till GUI. Prototypen är gjord i Delphi 3.0 och skall enbart ses som en fingervisning.
Vi ser tydligt hur mappar och brev presenteras. Rutan i nedre vänstra hörnet innehåller s.k. snabbadresser, där adressboken samt vanliga adresser visas. Med vanliga adresser menas adresser man ofta skickar brev till.