Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
JCyrAdm |
|
| 4.428571428571429;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 |