Coverage Report - de.tivsource.lib.jcyradm.JCyrAdm
 
Classes in this File Line Coverage Branch Coverage Complexity
JCyrAdm
0%
0/313
0%
0/80
4,429
 
 1  
 package de.tivsource.lib.jcyradm;
 2  
 
 3  
 import java.io.BufferedReader;
 4  
 import java.io.FileInputStream;
 5  
 import java.io.IOException;
 6  
 import java.io.InputStream;
 7  
 import java.io.InputStreamReader;
 8  
 import java.io.PrintStream;
 9  
 import java.math.BigDecimal;
 10  
 import java.net.Socket;
 11  
 import java.util.HashMap;
 12  
 import java.util.Locale;
 13  
 import java.util.Map;
 14  
 import java.util.Properties;
 15  
 import java.util.ResourceBundle;
 16  
 import java.util.regex.Pattern;
 17  
 
 18  
 import javax.net.ssl.SSLSocket;
 19  
 import javax.net.ssl.SSLSocketFactory;
 20  
 
 21  
 import org.apache.log4j.Logger;
 22  
 
 23  
 import de.tivsource.lib.jcyradm.exception.AuthenticationFailure;
 24  
 import de.tivsource.lib.jcyradm.exception.MailboxExists;
 25  
 import de.tivsource.lib.jcyradm.exception.NoLogMessagesFile;
 26  
 import de.tivsource.lib.jcyradm.exception.NoMailbox;
 27  
 import de.tivsource.lib.jcyradm.exception.NoPropertiesFile;
 28  
 import de.tivsource.lib.jcyradm.exception.NoQuota;
 29  
 import de.tivsource.lib.jcyradm.exception.NoServerAnswerFile;
 30  
 import de.tivsource.lib.jcyradm.exception.NoServerResponse;
 31  
 import de.tivsource.lib.jcyradm.exception.NoServerStream;
 32  
 import de.tivsource.lib.jcyradm.exception.NoValidMailboxName;
 33  
 import de.tivsource.lib.jcyradm.exception.QuotaNotInitialized;
 34  
 import de.tivsource.lib.jcyradm.exception.UnexpectedExtraArguments;
 35  
 import de.tivsource.lib.jcyradm.exception.UnexpectedServerAnswer;
 36  
 
 37  
 /**
 38  
  * JCyrAdm ist eine Libary die dazu dient eine Verbindung mit einem
 39  
  * Cyrus-Imap-Server herzustellen und um dann Verwaltungsoperationen
 40  
  * auszuführen (createMailbox, removeMailbox, etc. ).
 41  
  *
 42  
  * @author Marc Michele
 43  
  *
 44  
  */
 45  
 public class JCyrAdm {
 46  
 
 47  
     /**
 48  
      * Statischer Logger der Klasse JCyrAdm, zur Zeit gibt es Meldungen vom
 49  
      * Type INFO, TRACE und DEBUG.
 50  
      */
 51  0
     private static final Logger LOGGER = Logger.getLogger(JCyrAdm.class);
 52  
 
 53  
     /**
 54  
      * Der Standard Imap-Port.
 55  
      */
 56  
     private static final int DEFAULT_IMAP_PORT = 143;
 57  
 
 58  
     /**
 59  
      * Der Standard Imap-SSL-Port.
 60  
      */
 61  
     private static final int DEFAULT_IMAP_SSL_PORT = 993;
 62  
 
 63  
     /**
 64  
      * Die Standard Properties Datei.
 65  
      */
 66  
     private static final String DEFAULT_PROPERTIES_FILE = "jcyradm.properties";
 67  
 
 68  
     /**
 69  
      * Cyrus Imap-Host zu dem die Verbindung aufgebaut werden soll.
 70  
      */
 71  0
     private String host = "localhost";
 72  
 
 73  
     /**
 74  
      * Port auf dem der Cyrus Server lauscht.
 75  
      */
 76  
     private Integer port;
 77  
 
 78  
     /**
 79  
      * Default ACL.
 80  
      */
 81  0
     private String allacl = "lrswipcda";
 82  
 
 83  
     /**
 84  
      * Administrator mit dem die Verbindung aufgebaut werden soll.
 85  
      */
 86  
     private String administrator;
 87  
 
 88  
     /**
 89  
      * Passwort des Administrators.
 90  
      */
 91  
     private String password;
 92  
 
 93  
     /**
 94  
      * Belegter Speicherplatz der Mailbox.
 95  
      */
 96  
     private BigDecimal used;
 97  
 
 98  
 
 99  
     /**
 100  
      * Zugeordneter Speicherplatz der Mailbox.
 101  
      */
 102  
     private BigDecimal quota;
 103  
 
 104  
     /**
 105  
      * Prozentuale Belegung der Mailbox.
 106  
      */
 107  
     private BigDecimal load;
 108  
 
 109  
     /**
 110  
      * Willkommens-Nachricht des Servers.
 111  
      */
 112  
     private String welcomeMsg;
 113  
 
 114  
     /**
 115  
      * SSL-Socket-Verbindungs-Objekt.
 116  
      */
 117  
     private SSLSocket sslRequestSocket;
 118  
 
 119  
     /**
 120  
      * Socket-Verbindungs-Objekt.
 121  
      */
 122  
     private Socket requestSocket;
 123  
 
 124  
     /**
 125  
      * Der Stream mit dem zu Server geschrieben wird.
 126  
      */
 127  
     private PrintStream out;
 128  
 
 129  
     /**
 130  
      * Der Stream mit dem vom Server gelesen wird.
 131  
      */
 132  
     private BufferedReader in;
 133  
 
 134  
     /**
 135  
      * Map mit den ACLs der aktuellen Mailbox (User/ACL).
 136  
      */
 137  
     private Map<String, String> acls;
 138  
 
 139  
     /**
 140  
      * Map mit den Rückgabewerten des ID Kommandos.
 141  
      */
 142  0
     private Map<String, String> idMap = new HashMap<String, String>();
 143  
 
 144  
     /**
 145  
      * Property Datei in der die Einstellungen gespeichert werden.
 146  
      */
 147  
     private Properties props;
 148  
 
 149  
     /**
 150  
      * Datei mit den erwarteten Server-Anworten.
 151  
      */
 152  
     private ResourceBundle serverAnswers;
 153  
 
 154  
     /**
 155  
      * Datei mit den Log-Nachrichten.
 156  
      */
 157  
     private ResourceBundle logMessages;
 158  
 
 159  
     /**
 160  
      * Standard Konstruktor der Klasse JCyrAdm, dabei wird die interne
 161  
      * Properties-Datei benutzt.
 162  
      *
 163  
      * @throws NoPropertiesFile - Ausnahme wenn die Properties-Datei nicht
 164  
      *             gefunden wird.
 165  
      * @throws NoServerAnswerFile
 166  
      * @throws NoLogMessagesFile
 167  
      */
 168  
         public JCyrAdm() throws NoPropertiesFile, NoServerAnswerFile,
 169  
                         NoLogMessagesFile {
 170  0
         super();
 171  0
         LOGGER.debug("Aktuelle Sprache: " + Locale.getDefault().getLanguage());
 172  0
         props = new Properties();
 173  
 
 174  
         try {
 175  0
             LOGGER.debug("Lade Standard Properties Datei.");
 176  0
             InputStream inputStream = getClass().getClassLoader()
 177  0
                     .getResourceAsStream(DEFAULT_PROPERTIES_FILE);
 178  0
             props.load(inputStream);
 179  0
             inputStream.close();
 180  0
         } catch (Exception e1) {
 181  0
             throw new NoPropertiesFile();
 182  0
         }
 183  
 
 184  
         try {
 185  0
             LOGGER.debug("Lade Server Antworten Datei.");
 186  0
             serverAnswers = ResourceBundle.getBundle("server");
 187  0
         } catch (Exception e2) {
 188  0
             throw new NoServerAnswerFile();
 189  0
         }
 190  
 
 191  
         try {
 192  0
             LOGGER.debug("Lade Log-Nachrichten Datei.");
 193  0
             logMessages = ResourceBundle.getBundle("logging");
 194  0
         } catch (Exception e3) {
 195  0
             throw new NoLogMessagesFile();
 196  0
         }
 197  
 
 198  0
     } // Ende JCyrAdm()
 199  
 
 200  
     /**
 201  
      * Konstruktor der Klasse JCyrAdm, es muss eine Properties-Datei angegeben
 202  
      * werden.
 203  
      *
 204  
      * @param properties - Properties-Datei
 205  
      * @throws NoPropertiesFile - Ausnahme wenn die Properties-Datei nicht
 206  
      *             gefunden wird.
 207  
      * @throws NoServerAnswerFile
 208  
      * @throws NoLogMessagesFile
 209  
      */
 210  
         public JCyrAdm(String properties) throws NoPropertiesFile,
 211  
                         NoServerAnswerFile, NoLogMessagesFile {
 212  0
         super();
 213  0
         LOGGER.debug("Aktuelle Sprache: " + Locale.getDefault().getLanguage());
 214  0
         props = new Properties();
 215  
 
 216  
         try {
 217  0
             LOGGER.debug("Lade Properties Datei.");
 218  0
             InputStream inputStream = new FileInputStream(properties);
 219  0
             props.load(inputStream);
 220  0
             inputStream.close();
 221  0
         } catch (Exception e1) {
 222  0
             throw new NoPropertiesFile();
 223  0
         }
 224  
 
 225  
         try {
 226  0
             LOGGER.debug("Lade Server Antworten Datei.");
 227  0
             serverAnswers = ResourceBundle.getBundle("server");
 228  0
         } catch (Exception e2) {
 229  0
             throw new NoServerAnswerFile();
 230  0
         }
 231  
 
 232  
         try {
 233  0
             LOGGER.debug("Lade Log-Nachrichten Datei.");
 234  0
             logMessages = ResourceBundle.getBundle("logging");
 235  0
         } catch (Exception e3) {
 236  0
             throw new NoLogMessagesFile();
 237  0
         }
 238  
 
 239  0
     }// Ende JCyrAdm(String properties)
 240  
 
 241  
     /**
 242  
      * Methode um eine Verbindung zum Server aufzubauen, es muss der Parameter
 243  
      * "ssl" gesetzt werden. Wenn TRUE übergeben wird dann wird eine
 244  
      * SSL-Verbindung zum angebenen Port aufgebaut.
 245  
      *
 246  
      * @param ssl - Boolean mit dem zwischen SSL und Plain umgeschaltet wird.
 247  
      * @throws IOException - Unbekannter Host oder Unmöglich den Stream zu
 248  
      *             öffnen
 249  
      */
 250  
     public final void connect(final Boolean ssl) throws IOException {
 251  0
         LOGGER.debug(logMessages.getString("logger.trace.connect"));
 252  0
         if (ssl) {
 253  0
                 LOGGER.trace("öffne Verschlüsselte Verbindung");
 254  0
             if (isNull(port)) {
 255  0
                 port = DEFAULT_IMAP_SSL_PORT;
 256  
             }
 257  
             SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
 258  0
                     .getDefault();
 259  0
             sslRequestSocket = (SSLSocket) factory.createSocket(host, port);
 260  0
             out = new PrintStream(sslRequestSocket.getOutputStream());
 261  0
             out.flush();
 262  0
             in = new BufferedReader(new InputStreamReader(
 263  0
                     sslRequestSocket.getInputStream()));
 264  0
         } else {
 265  0
                 LOGGER.trace("öffne Ungesicherte Verbindung");
 266  0
             if (isNull(port)) {
 267  0
                 port = DEFAULT_IMAP_PORT;
 268  
             }
 269  0
             requestSocket = new Socket(host, port);
 270  0
             out = new PrintStream(requestSocket.getOutputStream());
 271  0
             out.flush();
 272  0
             in = new BufferedReader(new InputStreamReader(
 273  0
                     requestSocket.getInputStream()));
 274  
 
 275  
         }
 276  0
         welcomeMsg = in.readLine();
 277  0
         LOGGER.debug("Server >| " + welcomeMsg);
 278  0
     } // Ende connect()
 279  
 
 280  
     /**
 281  
          * Methode um die Verbindung zum Server zu trennen.
 282  
          * 
 283  
          * @throws IOException - wenn der Stream schon geschlossen ist oder
 284  
          *             Verbindung abgelaufen ist.
 285  
          */
 286  
     public final void disconnect() throws IOException {
 287  0
         LOGGER.trace(logMessages.getString("logger.trace.disconnect"));
 288  0
         if (sslRequestSocket != null) {
 289  0
                 LOGGER.trace("schließe Verschlüsselte Verbindung");
 290  0
             sslRequestSocket.close();
 291  
         } else {
 292  0
                 LOGGER.trace("schließe Ungesicherte Verbindung");
 293  0
             requestSocket.close();
 294  
         }
 295  0
     } // disconnect()
 296  
 
 297  
     /**
 298  
      * Unfertige Methode !!!! Diese Methode muss dringent überarbeitet werden.
 299  
      * Holt die Capability und setzt die Default-ACLs. .
 300  
      *
 301  
      * @throws IOException - InputStream/OutputStream geschlossen oder nicht
 302  
      *             vorhanden
 303  
      */
 304  
     public final void capability() throws IOException {
 305  0
         LOGGER.trace("capability() aufgerufen.");
 306  0
         sendCommand(". capability");
 307  0
         String line = in.readLine();
 308  0
         LOGGER.debug("Server >| " + line);
 309  
         //System.out.println("Server >| " + line);
 310  0
         line = in.readLine();
 311  0
         LOGGER.debug("Server >| " + line);
 312  
         //System.out.println("Server >| " + line);
 313  
 
 314  
         // // TODO Hier mus noch die Acl Abfrage hin ist jetzt von Hand gesetzt
 315  0
         allacl = "lrswipkxtecda";
 316  0
     }
 317  
 
 318  
     /**
 319  
      * Mit dieser Methode wird der Administrationsbenutzer am Server
 320  
      * angemeldet.
 321  
      *
 322  
      * @throws NoServerResponse - Keine Antwort vom Server erhalten.
 323  
      * @throws UnexpectedServerAnswer - Unerwartete Antwort vom Server.
 324  
      * @throws AuthenticationFailure 
 325  
      */
 326  
     public final void login() throws NoServerResponse, UnexpectedServerAnswer, AuthenticationFailure {
 327  0
         LOGGER.trace("login() aufgerufen.");
 328  0
         sendCommand(". login \"" + administrator + "\" \"" + password + "\"");
 329  
         try {
 330  
             // Lese Antwort vom Server
 331  0
             String line = in.readLine();
 332  0
             LOGGER.debug("Server >| " + line);
 333  
 
 334  
             // Wenn User oder Passwort falsch
 335  0
             if(serverAnswers.getString("server.answer.login.failed")
 336  0
                     .contentEquals(new StringBuffer(line))) {
 337  0
                 LOGGER.error("Fehler >| " + line);
 338  0
                 throw new AuthenticationFailure();
 339  
             }
 340  
             // Wenn Benutzer erfolgreich angemeldet wurde
 341  0
             else if(Pattern.matches(serverAnswers.getString("server.answer.login"), line)) {
 342  0
                 LOGGER.info("Authen >| " + line);
 343  
             }
 344  
             // In allen anderen Fällen
 345  
             else {
 346  0
                 System.out.println(serverAnswers.getString("server.answer.login"));
 347  0
                 LOGGER.error("Fehler >| " + line);
 348  0
                 throw new UnexpectedServerAnswer();
 349  
             }
 350  
 
 351  0
         } catch (IOException e) {
 352  0
             throw new NoServerResponse();
 353  0
         }
 354  0
     }// Ende login()
 355  
 
 356  
     /**
 357  
      * Mit dieser Methode meldet man sich vom Server ab, es werden auch alle
 358  
      * Streams geschlossen.
 359  
      *
 360  
      * @throws NoServerResponse - Keine Antwort vom Server.
 361  
      * @throws NoServerStream - Kein Stream vom Server vorhanden.
 362  
      * @throws UnexpectedServerAnswer - Unerwartete Server Antwort erhalten.
 363  
      */
 364  
     public final void logout() throws NoServerResponse, NoServerStream, UnexpectedServerAnswer {
 365  0
         LOGGER.trace("logout() aufgerufen.");
 366  
 
 367  
         // Sende Logout Nachricht
 368  0
         sendCommand(". logout");
 369  
 
 370  
         try {
 371  
             // Werte erste Server Antwort aus
 372  0
             String line = in.readLine();
 373  0
             LOGGER.debug("Server >| " + line);
 374  0
             if(!serverAnswers.getString("server.answer.logout")
 375  0
                     .contentEquals(new StringBuffer(line))) {
 376  0
                 LOGGER.error("Fehler >| " + line);
 377  0
                 throw new UnexpectedServerAnswer();
 378  
             }
 379  0
         } catch (IOException e) {
 380  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 381  0
             throw new NoServerResponse();
 382  0
         }
 383  
 
 384  
         try {
 385  
             // Werte zweite Server Antwort aus
 386  0
             String line = in.readLine();
 387  0
             LOGGER.debug("Server >| " + line);
 388  0
             if(!serverAnswers.getString("server.answer.ok")
 389  0
                     .contentEquals(new StringBuffer(line))) {
 390  0
                 LOGGER.error("Fehler >| " + line);
 391  0
                 throw new UnexpectedServerAnswer();
 392  
             }
 393  0
         } catch (IOException e) {
 394  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 395  0
             throw new NoServerResponse();
 396  0
         }
 397  
 
 398  
         try {
 399  
             // Schließe InputStream
 400  0
             in.close();
 401  0
         } catch (IOException e) {
 402  0
             LOGGER.error("Fehler >| Keine Stream vom Server vorhanden");
 403  0
             throw new NoServerStream();
 404  0
         }
 405  
         // Schließe OutputStream
 406  0
         out.close();
 407  0
     }// Ende logout()
 408  
 
 409  
     /**
 410  
      * Mit dieser Methode können die ACLs einer bestimmten Mailbox abgefragt
 411  
      * werden.
 412  
      *
 413  
      * @param mailbox - Die Mailbox für die die ACLs abgefragt werden sollen
 414  
      * @throws NoValidMailboxName - // TODO Dokumentation
 415  
      * @throws NoServerResponse 
 416  
      * @throws UnexpectedServerAnswer 
 417  
      */
 418  
     public final void acl(final String mailbox) throws NoValidMailboxName,
 419  
             NoServerResponse, UnexpectedServerAnswer {
 420  
         /*
 421  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 422  
          */
 423  0
         if (!isValid(mailbox)) {
 424  0
             LOGGER.error("Fehler >| Ungültiger Mailboxname");
 425  0
             throw new NoValidMailboxName();
 426  
         }
 427  
 
 428  
         /*
 429  
          * Kommando absetzen.
 430  
          */
 431  0
         sendCommand(". getacl \"user." + mailbox + "\"");
 432  
 
 433  
         /*
 434  
          * Erste Antwortzeile einlesen.
 435  
          */
 436  
         try {
 437  0
             String line = in.readLine();
 438  0
             LOGGER.debug("Server >| " + line);
 439  
 
 440  0
             if(!Pattern.matches(serverAnswers.getString("server.answer.acl"), line)) {
 441  0
                 LOGGER.error("Fehler >| " + line);
 442  0
                 throw new UnexpectedServerAnswer();
 443  
             }
 444  
 
 445  0
             acls = new HashMap<String, String>();
 446  0
             String keys[] = line.split(" ");
 447  0
             for(int i=0; i < keys.length; i++) {
 448  0
                 if(i > 2) {
 449  0
                     if(i % 2 == 1) {
 450  0
                         acls.put(keys[i], keys[i+1]);
 451  
                     }
 452  
                 }
 453  
             }
 454  
 
 455  0
         } catch (IOException e) {
 456  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 457  0
             throw new NoServerResponse();
 458  0
         }
 459  
 
 460  
         /*
 461  
          * Zweite Antwortzeile einlesen.
 462  
          */
 463  
         try {
 464  0
             String line = in.readLine();
 465  0
             LOGGER.debug("Server >| " + line);
 466  0
             if(!serverAnswers.getString("server.answer.ok")
 467  0
                     .contentEquals(new StringBuffer(line))) {
 468  0
                 LOGGER.error("Fehler >| " + line);
 469  0
                 throw new UnexpectedServerAnswer();
 470  
             }
 471  0
         } catch (IOException e) {
 472  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 473  0
             throw new NoServerResponse();
 474  0
         }
 475  0
     }// Ende acl(String)
 476  
 
 477  
     /**
 478  
      * Mit dieser Methode können für eine bestimmte Mailbox, Rechte für einen
 479  
      * bestimmten Benutzer gesetzt werden.
 480  
      *
 481  
      * @param mailbox - Die Mailbox für die die Rechte gesetzt werden sollen.
 482  
      * @param user - Benutzer für die die Rechte gelten sollen.
 483  
      * @param acl - Rechte die für den Benutzer gelten sollen.
 484  
      * @throws NoValidMailboxName -
 485  
      * @throws NoServerResponse 
 486  
      * @throws UnexpectedServerAnswer 
 487  
      */
 488  
     public final void setAcl(final String mailbox, final String user,
 489  
             final String acl) throws NoValidMailboxName, NoServerResponse, UnexpectedServerAnswer {
 490  
         /*
 491  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 492  
          */
 493  0
         if (!isValid(mailbox)) {
 494  0
             LOGGER.error("Fehler >| Ungültiger Mailboxname");
 495  0
             throw new NoValidMailboxName();
 496  
         }
 497  
 
 498  
         /*
 499  
          * Kommando absetzen.
 500  
          */
 501  0
         sendCommand(". setacl \"user." + mailbox + "\" \"" + user + "\" " + acl);
 502  
 
 503  
         /*
 504  
          * Einlesen der Antwortzeile.
 505  
          */
 506  
         try {
 507  0
             String line = in.readLine();
 508  0
             LOGGER.debug("Server >| " + line);
 509  0
             if(!serverAnswers.getString("server.answer.ok")
 510  0
                     .contentEquals(new StringBuffer(line))) {
 511  0
                 LOGGER.error("Fehler >| " + line);
 512  0
                 throw new UnexpectedServerAnswer();
 513  
             }
 514  0
         } catch (IOException e) {
 515  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 516  0
             throw new NoServerResponse();
 517  0
         }
 518  0
     }// Ende setAcl(String, String, String)
 519  
 
 520  
 
 521  
     /**
 522  
      * Mit dieser Methode können die Rechte einer Mailbox die für einen
 523  
      * bestimmten Benutzer existieren gelöscht werden.
 524  
      *
 525  
      * @param mailbox - Mailbox für die die Rechte gelöscht werden sollen.
 526  
      * @param user - Benutzer für den die Rechte gelöscht werden sollen.
 527  
      * @throws NoValidMailboxName - // TODO Dokumentation.
 528  
      * @throws NoServerResponse 
 529  
      * @throws UnexpectedServerAnswer 
 530  
      */
 531  
     public final void deleteAcl(final String mailbox, final String user)
 532  
             throws NoValidMailboxName, NoServerResponse, UnexpectedServerAnswer {
 533  
         /*
 534  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 535  
          */
 536  0
         if (!isValid(mailbox)) {
 537  0
             LOGGER.error("Fehler >| Ungültiger Mailboxname");
 538  0
             throw new NoValidMailboxName();
 539  
         }
 540  
 
 541  
         /*
 542  
          * Kommando absetzen.
 543  
          */
 544  0
         sendCommand(". deleteacl \"user." + mailbox + "\" \"" + user + "\"");
 545  
 
 546  
         /*
 547  
          * Antwortzeile auswerten.
 548  
          */
 549  
         try {
 550  0
             String line = in.readLine();
 551  0
             LOGGER.debug("Server >| " + line);
 552  0
             if(!serverAnswers.getString("server.answer.ok")
 553  0
                     .contentEquals(new StringBuffer(line))) {
 554  0
                 LOGGER.error("Fehler >| " + line);
 555  0
                 throw new UnexpectedServerAnswer();
 556  
             }
 557  0
         } catch (IOException e) {
 558  0
             LOGGER.error("Fehler >| Keine Antwort von Server erhalten");
 559  0
             throw new NoServerResponse();
 560  0
         }
 561  
 
 562  0
     }// Ende deleteAcl(String, String)
 563  
 
 564  
     /**
 565  
      * Methode zum berechnen der Quota der aktuellen Mailbox, die Werte können
 566  
      * über die entsprechenden Methoden abgerufen werden.
 567  
      *
 568  
      * @param mailbox - Mailbox für die die Quota berechnet werden soll.
 569  
      * @throws IOException - InputStream/OutputStream geschlossen oder nicht
 570  
      *             vorhanden
 571  
      * @throws NoMailbox - TODO doku
 572  
      * @throws NoQuota - TODO doku
 573  
      * @throws UnexpectedExtraArguments - TODO doku
 574  
      * @throws NoServerResponse - TODO doku
 575  
      * @throws NoValidMailboxName - TODO doku
 576  
      */
 577  
     public final void quota(final String mailbox) throws IOException,
 578  
             NoMailbox, NoQuota, UnexpectedExtraArguments, NoServerResponse,
 579  
             NoValidMailboxName {
 580  
 
 581  
         /*
 582  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 583  
          */
 584  0
         if (!isValid(mailbox)) {
 585  0
             LOGGER.error("Fehler >| Ungültiger Mailboxname");
 586  0
             throw new NoValidMailboxName();
 587  
         }
 588  
 
 589  
         /*
 590  
          * Absenden des Befehls und auslesen der ersten Ergebniszeile.
 591  
          */
 592  0
         sendCommand(". getquota \"user." + mailbox + "\"");
 593  0
         String line = in.readLine();
 594  0
         LOGGER.debug("Server >| " + line);
 595  
 
 596  
         /*
 597  
          * Prüfen ob der Server eine Antwort geschickt hat.
 598  
          */
 599  0
         if (isNull(line)) {
 600  0
             LOGGER.warn("Kein Antwort vom Server.");
 601  0
             throw new NoServerResponse();
 602  
         }
 603  
 
 604  
         /*
 605  
          * Wird geworfen wenn es die Mailbox nicht gibt.
 606  
          */
 607  0
         if (line.startsWith(". NO Mailbox")) {
 608  0
             LOGGER.warn("Mailbox existiert nicht.");
 609  0
             throw new NoMailbox();
 610  
         }
 611  
 
 612  
         /*
 613  
          * Wird geworfen wenn keine Quota gesetzt worden ist .
 614  
          */
 615  0
         if (line.startsWith(". NO Quota root does not exist")) {
 616  0
             LOGGER.warn("Es wurde bis jetzt noch keine Quota gesetzt.");
 617  0
             throw new NoQuota();
 618  
         }
 619  
 
 620  
         /*
 621  
          * Wird geworfen wenn der Methode unbekannte Parameter oder Zeichen
 622  
          * übergeben wurden.
 623  
          */
 624  0
         if (line.startsWith(". BAD Unexpected extra arguments to Getquota")) {
 625  0
             LOGGER.warn("Es wurden weiter Argumente dem Befehl hinzugefügt.");
 626  0
             throw new UnexpectedExtraArguments();
 627  
         }
 628  
 
 629  
         /*
 630  
          * Wenn keine Quota exsistiert bzw. die Antwort nicht "* QUOTA enthält
 631  
          * dann wird eine Exception geworfen.
 632  
          */
 633  0
         if (!line.startsWith("* QUOTA")) {
 634  0
             LOGGER.warn("In der Server-Anwort war keine Quota enthalten.");
 635  
             // TODO Exception hier hin.
 636  
         }
 637  
 
 638  
         /*
 639  
          * Setzen der Index Elemente.
 640  
          */
 641  0
         int start = line.lastIndexOf("(");
 642  0
         int end = line.lastIndexOf(")");
 643  
 
 644  
         /*
 645  
          * Zerlegen des Ergebnisses und schreiben der Quota und des
 646  
          * Benutzten Platzes in die Variablen.
 647  
          */
 648  0
         String[] storage = line.substring(start + 1, end).split(" ");
 649  0
         used = new BigDecimal(storage[1]);
 650  0
         quota = new BigDecimal(storage[2]);
 651  0
         LOGGER.debug(line.substring(start + 1, end));
 652  
 
 653  
 
 654  
         /*
 655  
          * Errechnen der Load und befüllung der entsprechenden Variable.
 656  
          */
 657  0
         load = used.multiply(new BigDecimal("100")).divide(quota, 2,
 658  
                 BigDecimal.ROUND_UP);
 659  
 
 660  
         /*
 661  
          * Auslesen der zweiten Antwortzeile
 662  
          */
 663  0
         line = in.readLine();
 664  0
         LOGGER.debug("Server >| " + line);
 665  
 
 666  
         /*
 667  
          * Prüfen ob der Server eine Antwort geschickt hat.
 668  
          */
 669  0
         if (isNull(line)) {
 670  0
             LOGGER.warn("Kein Antwort vom Server.");
 671  0
             throw new NoServerResponse();
 672  
         }
 673  
 
 674  
         /*
 675  
          * Exceptions je nach Antwortzeile.
 676  
          */
 677  0
         if (!line.startsWith(". OK")) {
 678  0
             LOGGER.warn(
 679  
                     "Der letzte Befehl wurde nicht erfolgreich ausgeführt."
 680  
                     );
 681  
             // TODO hier mus noch eine Exception hin
 682  
         }
 683  
 
 684  0
     }// Ende quota(String mailbox)
 685  
 
 686  
     /**
 687  
      * Methode zum setzten der Quota einer Mailbox.
 688  
      *
 689  
      * @param mailbox - Hier. // TODO Doku hier
 690  
      * @param quotaToSet - Hier. // TODO Doku hier
 691  
      * @throws IOException - TODO doku
 692  
      * @throws NoValidMailboxName -
 693  
      */
 694  
     public final void setQuota(final String mailbox,
 695  
             final BigDecimal quotaToSet)
 696  
             throws IOException, NoValidMailboxName {
 697  
         /*
 698  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 699  
          */
 700  0
         if (!isValid(mailbox)) {
 701  0
             LOGGER.warn("Ungültiger Mailboxname");
 702  0
             throw new NoValidMailboxName();
 703  
         }
 704  
 
 705  
         /*
 706  
          * Sende Kommando.
 707  
          */
 708  0
         sendCommand((new StringBuilder())
 709  0
                 .append(". setquota \"")
 710  0
                 .append("user.")
 711  0
                 .append(mailbox)
 712  0
                 .append("\" (STORAGE ")
 713  0
                 .append(quotaToSet)
 714  0
                 .append(")").toString());
 715  
 
 716  0
         String line = in.readLine();
 717  0
         LOGGER.debug("Server >| " + line);
 718  
         //System.out.println("Server >| " + line);
 719  
 
 720  
         // ". setquota \"$mb_name\" (STORAGE $quota)"
 721  
         // // TODO hier mus code hin
 722  0
     }// Ende setQuota()
 723  
 
 724  
     /**
 725  
      * Methode zum erstellen einer Mailbox mit dem Namen "mailbox".
 726  
      *
 727  
      * @param mailbox - String mit dem Namen der Mailbox (i.e.
 728  
      *            "mailboxname" ohne [user.])
 729  
      * @throws IOException - InputStream/OutputStream geschlossen oder nicht
 730  
      *             vorhanden
 731  
      * @throws MailboxExists - Die Mailbox die erstellt werden soll exsistiert
 732  
      *             bereits.
 733  
      * @throws NoServerResponse - //TODO Dokumentation
 734  
      * @throws NoValidMailboxName - //TODO Dokumentation
 735  
      */
 736  
     public final void createMailBox(final String mailbox) throws IOException,
 737  
             MailboxExists, NoServerResponse, NoValidMailboxName {
 738  
         /*
 739  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 740  
          */
 741  0
         System.out.println(mailbox);
 742  0
         if (!isValid(mailbox)) {
 743  
 
 744  0
             LOGGER.warn("Ungültiger Mailboxname");
 745  0
             throw new NoValidMailboxName();
 746  
         }
 747  
 
 748  
         /*
 749  
          * Kommando absetzen.
 750  
          */
 751  0
         sendCommand((new StringBuilder())
 752  0
                 .append(". create \"")
 753  0
                 .append("user.")
 754  0
                 .append(mailbox)
 755  0
                 .append("\"")
 756  0
                 .toString());
 757  
 
 758  
         /*
 759  
          * Antwortzeile auslesen.
 760  
          */
 761  0
         String line = in.readLine();
 762  0
         LOGGER.debug("Server >| " + line);
 763  
 
 764  
         /*
 765  
          * Prüfen ob es eine Serverantwort gibt.
 766  
          */
 767  0
         if (isNull(line)) {
 768  0
             LOGGER.warn("Keine Antwort vom Server.");
 769  0
             throw new NoServerResponse();
 770  
         }
 771  
 
 772  
         /*
 773  
          * Wirft Exception wenn es die Mailbox bereits gibt.
 774  
          */
 775  0
         if (line.startsWith(". NO Mailbox already exists")) {
 776  0
             LOGGER.warn("Die Mailbox existiert schon.");
 777  0
             throw new MailboxExists();
 778  
         }
 779  0
     }// Ende createMailBox()
 780  
 
 781  
     /**
 782  
      * Hier. // TODO Doku hier
 783  
      *
 784  
      * @param mailbox - Hier. // TODO Doku hier
 785  
      * @throws IOException - InputStream/OutputStream geschlossen oder nicht
 786  
      *             vorhanden
 787  
      * @throws NoValidMailboxName -
 788  
      */
 789  
     public final void deleteMailBox(final String mailbox) throws IOException,
 790  
             NoValidMailboxName {
 791  
         /*
 792  
          * Prüfen ob der übergebene Mailboxname gültig ist.
 793  
          */
 794  0
         if (!isValid(mailbox)) {
 795  0
             LOGGER.warn("Ungültiger Mailboxname");
 796  0
             throw new NoValidMailboxName();
 797  
         }
 798  
 
 799  
         /*
 800  
          * Setzen der Rechte für den Administrationsbenutzer
 801  
          */
 802  
         try {
 803  0
             setAcl(mailbox, administrator, allacl);
 804  0
         } catch (NoServerResponse e) {
 805  
             // TODO Auto-generated catch block
 806  0
             e.printStackTrace();
 807  0
         } catch (UnexpectedServerAnswer e) {
 808  
             // TODO Auto-generated catch block
 809  0
             e.printStackTrace();
 810  0
         }
 811  
 
 812  0
         sendCommand(". delete \"user." + mailbox + "\"");
 813  0
         String line = in.readLine();
 814  0
         LOGGER.debug("Server >| " + line);
 815  
         //System.out.println("Server >| " + line);
 816  0
     }// Ende deleteMailBox()
 817  
 
 818  
     /**
 819  
      * Methode zum setzen des Hostnamen oder der IP-Adresse des Servers mit dem
 820  
      * eine Verbindung aufgebaut werden soll. Falls der Host nicht gesetzt ist
 821  
      * wird localhost als hostname benutzt.
 822  
      *
 823  
      * @param hostname - Der Name oder die IP-Adresse des Servers zu dem eine
 824  
      *            Verbindung aufgebaut werden soll.
 825  
      */
 826  
     public final void setHost(final String hostname) {
 827  0
         this.host = hostname;
 828  0
     }// Ende setHost()
 829  
 
 830  
     /**
 831  
      * Methode um die Port-Nummer des Server zu verändern, normalerweise nicht
 832  
      * nötig, wenn der Server auf den Standard-Ports betrieben wird.
 833  
      *
 834  
      * @param portNumber - Port-Nummer die für die Verbindung zum Server
 835  
      *            benutzt werden soll.
 836  
      */
 837  
     public final void setPort(final Integer portNumber) {
 838  0
         this.port = portNumber;
 839  0
     }// Ende setPort()
 840  
 
 841  
     /**
 842  
      * Hier. // TODO Doku hier
 843  
      *
 844  
      * @param set - Hier. // TODO Doku hier
 845  
      */
 846  
     public final void setAdministrator(final String set) {
 847  0
         this.administrator = set;
 848  0
     }// Ende setAdministrator()
 849  
 
 850  
     /**
 851  
      * Hier. // TODO Doku hier
 852  
      *
 853  
      * @param set - Hier. // TODO Doku hier
 854  
      */
 855  
     public final void setPassword(final String set) {
 856  0
         this.password = set;
 857  0
     }// Ende setPasswort()
 858  
 
 859  
     /**
 860  
      * Liefert die Version des Server mit dem gerade eine Verbindung aufgebaut
 861  
      * ist.
 862  
      *
 863  
      * @return String - Cyrus Version
 864  
      * @throws IOException - InputStream/OutputStream geschlossen oder nicht
 865  
      *             vorhanden
 866  
      */
 867  
     public final String version() throws IOException {
 868  0
             sendCommand(". id NIL");
 869  0
         String line = in.readLine();
 870  0
         LOGGER.debug("Server >| " + line);
 871  
 
 872  0
         if (isNull(line)) {
 873  
             // TODO Hier kommt noch Exception
 874  0
             LOGGER.warn("Keine Server Antwort.");
 875  
         }
 876  
 
 877  0
         int start = line.indexOf("(");
 878  0
         int end = line.lastIndexOf(")");
 879  
 
 880  0
         String[] storage = line.substring(start + 1, end).split("\" \"");
 881  
 
 882  0
         for (int i = 0; i < storage.length; i++) {
 883  0
             idMap.put(storage[i], storage[i + 1]);
 884  0
             i++;
 885  
         }
 886  
 
 887  0
         line = in.readLine();
 888  0
         LOGGER.debug("Server >| " + line);
 889  
         //System.out.println("Server >| " + line);
 890  
 
 891  0
         return idMap.get("version").split(" ")[0];
 892  
     }// Ende version()
 893  
 
 894  
     /**
 895  
      * Mit Hilfe dieser Methode kann man sich die Wilkommensnachricht des Server
 896  
      * abfragen, die nach dem aufruf der Methode connect(Boolean ssl) empfangen
 897  
      * wurde.
 898  
      *
 899  
      * @return String - Willkommensnachricht des Servers.
 900  
      */
 901  
     public final String getWelcomeMsg() {
 902  0
         return welcomeMsg;
 903  
     }// Ende getWelcomeMsg()
 904  
 
 905  
     /**
 906  
      * TODO Doku
 907  
      * @return
 908  
      */
 909  
     public Map<String, String> getAcls() {
 910  0
         return acls;
 911  
     }// Ende getAcls;
 912  
 
 913  
     /**
 914  
      * Bevor die Methode getUsed() aufgerufen werden kann, muss die Methode
 915  
      * quota(String mailbox) aufgrufen werden. Die Methode getUsed() liefert
 916  
      * dann den benutzen Teil der Quota der Mailbox.
 917  
      *
 918  
      * @return BigDecimal - Benutzer Teil der Quota der Mailbox die mit der
 919  
      *         Methode quota(String mailbox) übergeben wurde.
 920  
      * @throws QuotaNotInitialized - TODO doku
 921  
      */
 922  
     public final BigDecimal getUsed() throws QuotaNotInitialized {
 923  0
         if (isNull(used)) {
 924  0
             throw new QuotaNotInitialized();
 925  
         }
 926  0
         return used;
 927  
     }// Ende getUsed()
 928  
 
 929  
     /**
 930  
      * Bevor die Methode getQuota() aufgerufen werden kann, muss die Methode
 931  
      * quota(String mailbox) aufgrufen werden. Die Methode getQuota() liefert
 932  
      * dann die aktuelle Quota der Mailbox.
 933  
      *
 934  
      * @return BigDecimal - Quota der Mailbox die mit der Methode quota(String
 935  
      *         mailbox) übergeben wurde.
 936  
      * @throws QuotaNotInitialized - TODO doku
 937  
      */
 938  
     public final BigDecimal getQuota() throws QuotaNotInitialized {
 939  0
         if (isNull(used)) {
 940  0
             throw new QuotaNotInitialized();
 941  
         }
 942  0
         return quota;
 943  
     }// Ende getQuota()
 944  
 
 945  
     /**
 946  
      * Bevor die Methode getLoad() aufgerufen werden kann, muss die Methode
 947  
      * quota(String mailbox) aufgrufen werden. Die Methode getLoad() liefert
 948  
      * dann die aktuelle Load der Mailbox.
 949  
      *
 950  
      * @return BigDecimal - Load der Mailbox die mit der Methode quota(String
 951  
      *         mailbox) übergeben wurde.
 952  
      * @throws QuotaNotInitialized - TODO doku
 953  
      */
 954  
     public final BigDecimal getLoad() throws QuotaNotInitialized {
 955  0
         if (isNull(used)) {
 956  0
             throw new QuotaNotInitialized();
 957  
         }
 958  0
         return load;
 959  
     }// Ende getLoad()
 960  
 
 961  
     /**
 962  
          * Hilfs-Methode um ein Kommando an den Server zu senden.
 963  
          * 
 964  
          * @param command - Kommando das an den Server gesendet werden soll.
 965  
          */
 966  
     private void sendCommand(final String command) {
 967  0
         out.println(command);
 968  0
         out.flush();
 969  0
         LOGGER.debug("Client >| " + command);
 970  0
     }// Ende sendCommand()
 971  
     
 972  
     /**
 973  
      * Hilfs-Methode die prüft ob ein Object Null ist.
 974  
      *
 975  
      * @param isNull - Objekt das getestet werden soll.
 976  
      * @return Boolean - Wahrheitswert: True wenn das Objekt Null ist.
 977  
      */
 978  
     private Boolean isNull(final Object isNull) {
 979  0
             return isNull != null ? false : true;
 980  
     }// Ende isNull()
 981  
 
 982  
     /**
 983  
      * Hilfs-Methode die testet ob ein String ein gültiger String im Sinne
 984  
      * einer Cyrus Mailbox ist.
 985  
      *
 986  
      * @param mbString - String der als Mailbox übergeben wurde.
 987  
      * @return Boolean - Wenn gültig dann True.
 988  
      */
 989  
     private Boolean isValid(final String mbString) {
 990  0
         return Pattern.matches("[a-zA-Z_]*", mbString)? true : false;
 991  
     }
 992  
 
 993  
     /**
 994  
          * Hilfs-Methode die dazu dient den String einer zu einem bestimmtem
 995  
          * Schlüssel aus der Eigenschaftsdatei zu holen.
 996  
          * 
 997  
          * @param text - Schlüssel unter dem der String abgelegt ist.
 998  
          * @return String - Der enthaltente String zum angegebenen Schlüssel oder
 999  
          *         wenn der Schlüssel nicht gefunden wurde der übergebene String.
 1000  
          */
 1001  
     @Deprecated
 1002  
     private String getText(String text) {
 1003  0
         if ((props != null) && (props.getProperty(text) != null)) {
 1004  0
             return props.getProperty(text);
 1005  
         }
 1006  0
         return text;
 1007  
     }// Ende getText()
 1008  
 
 1009  
     
 1010  
 }// Ende class