From ffbbafde7703fde2757350f5c9d9ef1a10ec68a5 Mon Sep 17 00:00:00 2001 From: Asecave Date: Mon, 17 Jan 2022 09:09:47 +0100 Subject: [PATCH] Controller (untested) --- MyMail.java | 447 +++++++++++++++++++++++++++----------------------- package.bluej | 74 ++++++--- 2 files changed, 295 insertions(+), 226 deletions(-) diff --git a/MyMail.java b/MyMail.java index bad485e..66f8355 100644 --- a/MyMail.java +++ b/MyMail.java @@ -1,252 +1,285 @@ public class MyMail { - public static final String POP3_SERVER = "127.0.0.1"; + public static final String POP3_SERVER = "127.0.0.1"; - public static final int POP3_PORT = 110; + public static final int POP3_PORT = 110; - public static final String POP3_USER = "user1"; + public static final String POP3_USER = "user1"; - public static final String POP3_PASS = "user1"; + public static final String POP3_PASS = "user1"; + public static void main(String[] args) { + // new MyMail(); + new MyMail("pop3.neugebauer.cc", 110, "informatik@neugebauer.cc", "ifq2_user1"); + } - public static void main( String[] args ) { - new MyMail(); - //new MyMail("pop3.neugebauer.cc", 110, "informatik@neugebauer.cc", "ifq2_user1"); - } + private String ip; - private String ip; + private int port; - private int port; + private Connection con; - private Connection con; + private MyMailGUI gui; - private MyMailGUI gui; + private String user; - private String user; + private String password; - private String password; + private String lastError; - private String lastError; + /** + * Verbindet zu einem lokalen POP3-Server. + */ + public MyMail() { + this(POP3_SERVER, POP3_PORT, POP3_USER, POP3_PASS); + } - /** - * Verbindet zu einem lokalen POP3-Server. - */ - public MyMail() { - this(POP3_SERVER, POP3_PORT, POP3_USER, POP3_PASS); - } + public MyMail(String pIP, String pUser, String pPassword) { + this(pIP, 110, pUser, pPassword); + } - public MyMail( String pIP, String pUser, String pPassword ) { - this(pIP, 110, pUser, pPassword); - } + public MyMail(String pIP, int pPort, String pUser, String pPassword) { + ip = pIP; + port = pPort; + user = pUser; + password = pPassword; - public MyMail( String pIP, int pPort, String pUser, String pPassword ) { - ip = pIP; - port = pPort; - user = pUser; - password = pPassword; + // GUI erstellen und Status setzen. + gui = new MyMailGUI(this); + gui.setStatus("App gestartet"); + + connectToServer(); + login(); + } - // GUI erstellen und Status setzen. - gui = new MyMailGUI(this); - gui.setStatus("App gestartet"); - } + /** + * Stellt die Verbindung zum POP3-Server her. + *

+ * Erstellt ein {@link Connection}-Objekt für die Verbindung zum Server mit der + * IP {@link #ip} und dem Port {@link #port}. Laut RFC1939 sendet der + * POP3-Server als Erstes eine Begrüßungsnachricht zur Bestätigung der + * Verbindung: + * + *

Once the TCP connection has been opened by a POP3 client, the + * POP3 server issues a one line greeting. This can be any positive response. An + * example might be: S: +OK POP3 server ready
+ *

+ * Gibt es beim Verbindungsaufbau einen Fehler, gibt die Methode {@code false} + * zurück und setzt {@link #lastError} auf eine sinnvolle Fehlermeldung. + *

+ * Das {@code Connection}-Objekt wird in {@link #con} gespeichert. + * + * @return {@code true} oder {@code false} + * @link https://datatracker.ietf.org/doc/html/rfc1939#section-4 + */ + private boolean connectToServer() { + // TODO: Connection-Objekt initialisieren + con = new Connection(ip, port); - /** - * Stellt die Verbindung zum POP3-Server her. - *

- * Erstellt ein {@link Connection}-Objekt für die Verbindung zum Server - * mit der IP {@link #ip} und dem Port {@link #port}. Laut RFC1939 sendet - * der POP3-Server als Erstes eine Begrüßungsnachricht zur Bestätigung der - * Verbindung: - * - *

- * Once the TCP connection has been opened by a POP3 client, the POP3 - * server issues a one line greeting. This can be any positive - * response. An example might be: - * S: +OK POP3 server ready - *
- *

- * Gibt es beim Verbindungsaufbau einen Fehler, gibt die Methode {@code false} - * zurück und setzt {@link #lastError} auf eine sinnvolle Fehlermeldung. - *

- * Das {@code Connection}-Objekt wird in {@link #con} gespeichert. - * - * @return {@code true} oder {@code false} - * @link https://datatracker.ietf.org/doc/html/rfc1939#section-4 - */ - private boolean connectToServer() { - // TODO: Connection-Objekt initialisieren - con = null; + // Begrüssungsnachricht des Servers empfangen und prüfen + String mes = con.receive(); + if (mes == null || mes.startsWith("-ERR")) { + // Keine "positive response" :-( + // Setze einen Fehler und gib "false" zurück. + lastError = "Der POP3-Server reagiert nicht!"; + return false; + } - // Begrüssungsnachricht des Servers empfangen und prüfen - String mes = con.receive(); - if( mes == null || mes.startsWith("-ERR") ) { - // Keine "positive response" :-( - // Setze einen Fehler und gib "false" zurück. - lastError = "Der POP3-Server reagiert nicht!"; - return false; - } + // Verbindung erfolgreich + return true; + } - // Verbindung erfolgreich - return true; - } + /** + * Authentifiziert den Nutzer beim POP3-Server. + *

+ * Die Methode nutzt die {@code USER} / {@code PASS} Befehle zur Anmeldung mit + * dem {@link #user} und {@link #password}. Sie erwartet, dass zuvor erfolgreich + * eine Verbindung mit {@link #connectToServer()} hergestellt wurde. + *

+ * Hat die Anmeldung Erfolg, wird {@code true} zurückgegeben. Andernfalls + * {@code false} und {@link #lastError} wird auf eine sinnvolle Fehler- meldung + * gesetzt. + * + * @return {@code true} oder {@code false} + * @link https://datatracker.ietf.org/doc/html/rfc1939#page-13 + */ + private boolean login() { + String mes = ""; // Speicher für die Antworten des Servers - /** - * Authentifiziert den Nutzer beim POP3-Server. - *

- * Die Methode nutzt die {@code USER} / {@code PASS} Befehle zur - * Anmeldung mit dem {@link #user} und {@link #password}. Sie erwartet, dass - * zuvor erfolgreich eine Verbindung mit {@link #connectToServer()} - * hergestellt wurde. - *

- * Hat die Anmeldung Erfolg, wird {@code true} zurückgegeben. Andernfalls - * {@code false} und {@link #lastError} wird auf eine sinnvolle Fehler- - * meldung gesetzt. - * - * @return {@code true} oder {@code false} - * @link https://datatracker.ietf.org/doc/html/rfc1939#page-13 - */ - private boolean login() { - String mes = ""; // Speicher für die Antworten des Servers + // TODO: Implementieren + // USER Kommando senden und Antwort prüfen + con.send("USER " + user); + mes = con.receive(); + if (mes == null || mes.startsWith("-ERR")) { + lastError = "Ungueltiger Benutzername!"; + return false; + } + // PASS Kommando senden und Antwort prüfen + con.send("PASS " + password); + mes = con.receive(); + if (mes == null || mes.startsWith("-ERR")) { + lastError = "Ungueltiges Passwort!"; + return false; + } + // Anmeldung war erfolgreich + return true; + } - // TODO: Implementieren - // USER Kommando senden und Antwort prüfen + /** + * Ermittelt die Anzahl an Nachrichten auf dem Server. + *

+ * Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit + * {@link #connectToServer()} hergestellt wurde und nutzt dann den {@code STAT} + * Befehl, um die Anzahl der Mails zu ermitteln. + * + * @return Die Anzahl an Mails auf dem Server + * @link https://datatracker.ietf.org/doc/html/rfc1939#page-6 + */ + public int getMessageCount() { + String mes = ""; - // PASS Kommando senden und Antwort prüfen + // TODO: Implementieren + // Sende den STAT Befehl + // Prüfe, ob die Antwort ein Fehler ist + // Schneide den Teil zwischen den Leerzeichen aus + // Finde die Leerzeichen mit indexOf(" ") + // Ermittele den Text mit substring(von, bis) + // Wandele mit Integer.parseInt() in eine Zahl um + con.send("STAT"); + mes = con.receive(); + int space1 = mes.indexOf(" "); + int space2 = mes.lastIndexOf(" ", space1); + return Integer.parseInt(mes.substring(space1, space2)); - // Anmeldung war erfolgreich - return true; - } + // ---=== Alternativ ===--- + // return Integer.parseInt(mes.split(" ")[1]); + } - /** - * Ermittelt die Anzahl an Nachrichten auf dem Server. - *

- * Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit - * {@link #connectToServer()} hergestellt wurde und nutzt dann den - * {@code STAT} Befehl, um die Anzahl der Mails zu ermitteln. - * - * @return Die Anzahl an Mails auf dem Server - * @link https://datatracker.ietf.org/doc/html/rfc1939#page-6 - */ - public int getMessageCount() { - String mes = ""; + /** + * Ruft alle vorhandenen Mails vom Server ab und fügt sie der {@link #gui} + * hinzu. + */ + public void getAllMails() { + gui.setStatus("Rufe Mails vom Server ab.."); + gui.clearAllMails(); // Gui leeren + lastError = null; // Zu Beginn gibt es noch keinen Fehler - // TODO: Implementieren - // Sende den STAT Befehl - // Prüfe, ob die Antwort ein Fehler ist - // Schneide den Teil zwischen den Leerzeichen aus - // Finde die Leerzeichen mit indexOf(" ") - // Ermittele den Text mit substring(von, bis) - // Wandele mit Integer.parseInt() in eine Zahl um - return 0; - } + // Verbindung erstellen und prüfen + boolean connected = connectToServer(); + if (!connected) { + // Letzten Fehler anzeigen (wird in connectToServer gesetzt). + gui.setError(lastError); + return; // Abbrechen + } - /** - * Ruft alle vorhandenen Mails vom Server ab und fügt sie der {@link #gui} - * hinzu. - */ - public void getAllMails() { - gui.setStatus("Rufe Mails vom Server ab.."); - gui.clearAllMails(); // Gui leeren - lastError = null; // Zu Beginn gibt es noch keinen Fehler + // Anmeldung durchführen und prüfen + // Hinweis: Nutze die login() Methode + boolean loggedIn = login(); + if (!loggedIn) { + // Letzten Fehler anzeigen (wird in connectToServer gesetzt). + gui.setError(lastError); + return; // Abbrechen + } - // Verbindung erstellen und prüfen - boolean connected = connectToServer(); - if( !connected ) { - // Letzten Fehler anzeigen (wird in connectToServer gesetzt). - gui.setError(lastError); - return; // Abbrechen - } + // Anzahl Mails auf dem Server abfragen + int mailCount = 0; - // Anmeldung durchführen und prüfen - // Hinweis: Nutze die login() Methode + // Abruf der Mails nach fortlaufender Nummer + for (int i = 1; i <= mailCount; i++) { + // Mail abrufen (nutze getMail(int)) + // Mail der GUI hinzufügen (nutze gui.addMailToLost(Mail)) + gui.addMailToList(getMail(i)); + } - // Anzahl Mails auf dem Server abfragen - int mailCount = 0; + // Verbindung beenden + con.send("QUIT"); + con.close(); - // Abruf der Mails nach fortlaufender Nummer - for( int i = 1; i <= mailCount; i++ ) { - // Mail abrufen (nutze getMail(int)) - // Mail der GUI hinzufügen (nutze gui.addMailToLost(Mail)) - } + if (lastError != null) { + // Es gab einen Fehler + gui.setError(lastError); + } else { + // Kein Fehler + gui.setStatus("Liste der Mails erfolgreich geladen."); + } + } - // Verbindung beenden - con.send("QUIT"); - con.close(); + /** + * Ruft die Mail mit der Nummer pNumber vom Server ab und gibt sie + * als {@link Mail}-Objekt zurück. + *

+ * Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit + * {@link #connectToServer()} hergestellt wurde. + *

+ * Tritt ein Fehler auf, gibt die Methode {@code null} zurück und setzt + * {@link #lastError} auf eine sinnvolle Nachricht. + * + * @param pNumber Die Nummer einer E-Mail auf dem Server + * @return Ein Mail-Objekt oder {@code null}. + */ + public Mail getMail(int pNumber) { + String mes = ""; // Speicher für Antworten des Servers - if( lastError != null ) { - // Es gab einen Fehler - gui.setError(lastError); - } else { - // Kein Fehler - gui.setStatus("Liste der Mails erfolgreich geladen."); - } - } + // Prüfen, ob es eine Mail mit der Nummer pNumber gibt + int count = getMessageCount(); + if (pNumber > count) { + lastError = "Es gibt keine Mail " + pNumber + "!"; + } - /** - * Ruft die Mail mit der Nummer pNumber vom Server ab und - * gibt sie als {@link Mail}-Objekt zurück. - *

- * Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit - * {@link #connectToServer()} hergestellt wurde. - *

- * Tritt ein Fehler auf, gibt die Methode {@code null} zurück und setzt - * {@link #lastError} auf eine sinnvolle Nachricht. - * - * @param pNumber Die Nummer einer E-Mail auf dem Server - * @return Ein Mail-Objekt oder {@code null}. - */ - public Mail getMail( int pNumber ) { - String mes = ""; // Speicher für Antworten des Servers + // Mail abrufen (RETR) + con.send("RETR " + pNumber); + mes = con.receive(); - // Prüfen, ob es eine Mail mit der Nummer pNumber gibt + while (!mes.equals(".")) { + // Text der Mail parsen + // Verarbeite die Metadaten, vor allem: + // - Nummer der Mail + // - Subject + // - From + // - Date + // Wenn der Textkörper anfängt, speichere alle Zeilen in einen String + // + // Hinweis: Denke daran die Maskierung des Enzeichens "." rückgängig zu + // machen. + // Tipp: Merk dir in einem boolean, ob du im Textkörper oder im Header bist. + + mes = con.receive(); + System.out.println(mes); + } // end of while - // Mail abrufen (RETR) + return null; + } - while( !mes.equals(".") ) { - // Text der Mail parsen - // Verarbeite die Metadaten, vor allem: - // - Nummer der Mail - // - Subject - // - From - // - Date - // Wenn der Textkörper anfängt, speichere alle Zeilen in einen String - // - // Hinweis: Denke daran die Maskierung des Enzeichens "." rückgängig zu machen. - // Tipp: Merk dir in einem boolean, ob du im Textkörper oder im Header bist. - } // end of while + /** + * Löscht eine Mail vom Server. + *

+ * Die Methode stellt eine Verbindung zum Server her, markiert die übergebene + * Mail als gelöscht und beendet die Verbindung. + *

+ * Tritt ein Fehler auf, bricht die Methode ab und setzt den Status der GUI auf + * eine sinnvolle Fehlermeldung. + * + * Achtung: Es wird die Mail mit derselben Nummer wie pMail + * gelöscht. Es wird nicht garantiert, dass dies auch dieselbe Mail ist. + * + * @param pMail Das Mailobjekt, das gelöscht werden soll. + * @todo Vor Löschen prüfen, ob die Mail auf dem Server dieselbe wie pMail + * ist. + */ + public void deleteMail(Mail pMail) { + // Verbindung erstellen und prüfen - return null; - } + // Anmeldung durchführen und prüfen - /** - * Löscht eine Mail vom Server. - *

- * Die Methode stellt eine Verbindung zum Server her, markiert die - * übergebene Mail als gelöscht und beendet die Verbindung. - *

- * Tritt ein Fehler auf, bricht die Methode ab und setzt - * den Status der GUI auf eine sinnvolle Fehlermeldung. - * - * Achtung: Es wird die Mail mit derselben Nummer wie pMail - * gelöscht. Es wird nicht garantiert, dass dies auch dieselbe Mail ist. - * - * @param pMail Das Mailobjekt, das gelöscht werden soll. - * @todo Vor Löschen prüfen, ob die Mail auf dem Server dieselbe wie pMail ist. - */ - public void deleteMail( Mail pMail ) { - // Verbindung erstellen und prüfen + // Prüfen, ob eine Mail mit der Nummer vorhanden ist + // Hinweis: Die Nummer der Mail ist über pMail.getNumber() abrufbar - // Anmeldung durchführen und prüfen + // Mail als gelöscht markieren - // Prüfen, ob eine Mail mit der Nummer vorhanden ist - // Hinweis: Die Nummer der Mail ist über pMail.getNumber() abrufbar + // Löschung ausführen und Verbindung beenden. - // Mail als gelöscht markieren - - // Löschung ausführen und Verbindung beenden. - - // Mail aus der GUI entfernen und neu aufbauen.s - gui.removeMailFromList(pMail); - } + // Mail aus der GUI entfernen und neu aufbauen.s + gui.removeMailFromList(pMail); + } } diff --git a/package.bluej b/package.bluej index 35b96ed..70a8413 100644 --- a/package.bluej +++ b/package.bluej @@ -1,23 +1,38 @@ #BlueJ package file -dependency1.from=MailClient +dependency1.from=MyMail dependency1.to=Connection dependency1.type=UsesDependency -editor.fx.0.height=777 -editor.fx.0.width=804 -editor.fx.0.x=36 -editor.fx.0.y=23 -objectbench.height=101 -objectbench.width=776 +dependency2.from=MyMail +dependency2.to=MyMailGUI +dependency2.type=UsesDependency +dependency3.from=MyMail +dependency3.to=Mail +dependency3.type=UsesDependency +dependency4.from=MyMailGUI +dependency4.to=MyMail +dependency4.type=UsesDependency +dependency5.from=MyMailGUI +dependency5.to=Mail +dependency5.type=UsesDependency +dependency6.from=MyMailGUI +dependency6.to=List +dependency6.type=UsesDependency +editor.fx.0.height=0 +editor.fx.0.width=0 +editor.fx.0.x=0 +editor.fx.0.y=0 +objectbench.height=93 +objectbench.width=760 package.divider.horizontal=0.6 -package.divider.vertical=0.8007380073800738 -package.editor.height=427 -package.editor.width=662 +package.divider.vertical=0.8 +package.editor.height=393 +package.editor.width=649 package.editor.x=40 package.editor.y=172 package.frame.height=600 package.frame.width=800 -package.numDependencies=1 -package.numTargets=2 +package.numDependencies=6 +package.numTargets=5 package.showExtends=true package.showUses=true project.charset=UTF-8 @@ -27,16 +42,37 @@ readme.width=47 readme.x=10 readme.y=10 target1.height=50 -target1.name=Connection +target1.name=MyMail target1.showInterface=false target1.type=ClassTarget -target1.width=90 -target1.x=350 -target1.y=40 +target1.width=80 +target1.x=140 +target1.y=10 target2.height=50 -target2.name=MailClient +target2.name=Mail target2.showInterface=false target2.type=ClassTarget target2.width=80 -target2.x=110 -target2.y=150 +target2.x=70 +target2.y=70 +target3.height=50 +target3.name=Connection +target3.showInterface=false +target3.type=ClassTarget +target3.width=100 +target3.x=350 +target3.y=40 +target4.height=50 +target4.name=List +target4.showInterface=false +target4.type=ClassTarget +target4.width=150 +target4.x=10 +target4.y=130 +target5.height=50 +target5.name=MyMailGUI +target5.showInterface=false +target5.type=ClassTarget +target5.width=90 +target5.x=160 +target5.y=70