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) *

Inledning

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.

Allmänna designbeslut

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.

 

 

    1. Klassdiagram
    2. Klasser
      1. TLetter (Brev)
        1. Metoder
        2. TLetter(long int ID, Theader& header) Extern funktion

          Konstruktor 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)

        3. Attribut

        TFolder& folder Privat

        Referens 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…)

      2. THeader (Header)
        1. Metoder
        2. THeader(CString& to, CString& from, Cstring& CC, Cstring& subject, int flags)
          Interfacefunktion

          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

        3. Attribut

        CList <TAdress> to Privat

        CList <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

      3. TAddress (Adress)
        1. Metoder
        2. TAddress(CString address, CString name) Interfacefunktion

          CString& GetAddress() Interfacefunktion

          CString& GetName() Interfacefunktion

        3. Attribut

        CString address privat

        CString name privat

         

      4. TRawData
      5. 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( );

        }

        1. Metoder
        2. TRawData(CString* s) Extern funktion

          Skapar 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.

        3. Attribut

        char* mem Privat

        Pekare 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.

      6. TFolder (Mapp)
      7. TFolder är den klass som hanterar mappsystemet i mailklienten.

        1. Metoder

TFolder(CString name, long int=NO_ID) Extern funktion

    1. Sätter namn och ID på foldern
    2. Initierar folders och letters.
    3. Anropar Save på sig själv.

Om 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 do

if l is modified

l.Save()

for each subfolder f do

if f is modified

f.Save()

void Rename(CString name) Interfacefunktion

    1. Sätter namn på mappen
    2. Sätter modified-flaggan

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

    1. Lägger till brevet i brevlistan letters
    2. Anropar TLetter::SetfolderID(ID). Om det redan finns ett ID i brevet genereras undantaget ELetterHasParent.

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

    1. Lägger till subfolder f i folderlistan. Om f redan ligger i foldern generas undantaget EAlreadyInFolder. Undantag bör också genereras om f förekommer i föräldraträdet till den aktuella foldern för att undvika att en folder flyttas ner i sig själv. Jfr filsystem och operationen "move foo foo/bar/".
    2. Anropar f.ChangeParent(this) för att ställa föräldraskapet till rätta.

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 lettersloaded

LoadLetters()

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 do

s.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.

      1. Attribut
      2. long int folderID Privat

        Folderns 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 Privat

        Lista ö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.

      3. Undantag

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.

    1. TPostOffice (Postkontor)
    2. 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.

      1. Metoder

void 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.

      1. Attribut
      2. TMailBox mailBox Publik

        Brevlå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

        }

      3. Undantag

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.

    1. TCodeManager (Kodningshanterare)
    2. 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.

      1. Metoder
      2. CString 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å)

      3. Attribut

      List of TEncoder encoder Privat

      Kodare 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.

    3. TMailBox (Brevlåda)
    4. 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++.

      1. Metoder
      2. TMailBox() intern funktion

        Skapar 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.

      3. Attribut

      TReceiveModule in;

      TSendModule out;

    5. TSendModule
      1. Metoder
      2. 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.

         

      3. Attribut

      CString hostname

    6. TRecieveModule
      1. Metoder
      2. bool 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.

      3. Attribut

      CString hostname, username, password

    7. TIO (Fil IO)
      1. Metoder
      2. TIO() intern funktion

        Initierar 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.

      3. Attribut

      TID nextAvailID

      Container folderIDTab {Mappning av ID till objekt}

    8. TMMap
      1. Metoder
      2. TMMap(CString filename, int readwrite, int size) extern funktion

        Initierar 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.

      3. Attribut

CString filename;

Interna strukturer för filhantag (hFile) och minnemappning (hMap);

char *pointer;

    1. Scenarion
      1. Skicka brev

    1. Användaren editerar brevet i GUIt.
    2. GUIt skapar ett brevobjekt med kontruktorn i TLetter.
    3. GUIt anropar postOffice.PlaceLetter(letter,OUTBOX).
    4. Postkontoret anropar mailBox.PrepareToSend().
    5. Brevlådan försöker koppla upp sig mot SMTP-servern. Om detta misslyckas startar brevlådan en retrytimer och upprepar förfarandet tills den kommer åt SMTP-servern.
    6. Brevlådan anropar postOffice.ListOutgoingMail() i postkontoret.
    7. Postkontoret tar ur alla brev från Outbox med hjälp av outBox.GetLetters och outBox.RemoveLetter (för varje brev i listan från GetLetters) och returnerar listan till brevlådan.
    8. Brevlådan anropar sendModule.Send(letter) för varje brev i listan.
    9. Brevlådan sätter statusflaggor i breven (sent, error, received).
    10. Brevlådan skickar tillbaks listan på brev med postOffice.ReceiveLetters().
    11. Postkontoret sorterar breven enligt statusflaggorna. De med sent satt läggs i Sent Mail, de med fel skickas tillbaks till OutBox och så vidare.
    1. Ta emot brev

    1. Brevlådan anropar receiveModule.Check periodiskt och kollar om det finns brev. Om det gör det anropas receiveModule.Receive() för varje brev som väntar. Receive() anropas tills NULL-pekaren erhålls.
    2. Från Receive() erhålls TRawData, så brevlådan konstruerar brevobjekt av denna med hjälp av TLetter::TLetter(TRawData).
    3. Brevlådan bygger en lista av de inkomna breven
    4. Brevlådan anropar postOffice.ReceiveLetters(letterlist).
    5. Postkontoret lägger inkomna brev i InBox. Alternativt: Anropar ruleManager.ApplyAllRules(letterlist) om regelhanteraren är implementerad.
    1. Skriva brev

    1. Användaren klickar på Nytt brev.
    2. GUI startar ett editeringsfönster.
    3. Användaren skriver brevet och trycker sedan på Sänd.
    4. GUIt skapar ett nytt brevobjekt med konstruktorn TLetter::TLetter(CString text, THeader header).
    5. GUIt utför postOffice.PlaceLetter(Letter) på brevet (Brevet läggs som default i OutBox).
    6. GUIt stänger editeringsfönstret.

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.

 

    1. Editera brev

    1. Användaren dubbelklickar på brevhuvudet.
    2. GUI anropar letter.GetHeader()
    3. GUI kollar status på headern med header.GetFlag(lockedflag).
    4. Om brevet är låst, avbryt. Annars
    5. Lås brevet för editering med header.SetFlag(lockedflag)
    6. ….. se Skriva Brev
    7. GUIt låser upp brevet med header.ClearFlag(lockedflag)
    8. GUIt stänger editeringsfönstret.

 

    1. Visa brev

    1. Användaren klickar på brevhuvud i listan
    2. GUI: TLetter.GetReadableText()
    3. TLetter: PostOffice.GetCodeManager()
    4. TLetter: TCodeMananager.DecodeRawData(rawData)
    5. GUI: Får tillbaka en CString innehållande brödtexten i brevet
    6. GUI: TLetter.GetHeader()
    7. GUI: THeader.GetTo() osv…
    8. GUI: får tillbaka ett antal CStrings
    9. GUI: Visar utplockad information på skärmen

 

 

 

    1. Grafiskt gränssnitt (GUI)

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.