001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.net.imap;
019
020 import java.io.IOException;
021
022 /**
023 * The IMAPClient class provides the basic functionalities found in an
024 * IMAP client.
025 */
026 public class IMAPClient extends IMAP
027 {
028
029 // --------- commands available in all states
030
031 /**
032 * Send a CAPABILITY command to the server.
033 * @return {@code true} if the command was successful,{@code false} if not.
034 * @exception IOException If a network I/O error occurs
035 */
036 public boolean capability() throws IOException
037 {
038 return doCommand (IMAPCommand.CAPABILITY);
039 }
040
041 /**
042 * Send a NOOP command to the server. This is useful for keeping
043 * a connection alive since most IMAP servers will timeout after 10
044 * minutes of inactivity.
045 * @return {@code true} if the command was successful,{@code false} if not.
046 * @exception IOException If a network I/O error occurs.
047 */
048 public boolean noop() throws IOException
049 {
050 return doCommand (IMAPCommand.NOOP);
051 }
052
053 /**
054 * Send a LOGOUT command to the server. To fully disconnect from the server
055 * you must call disconnect().
056 * A logout attempt is valid in any state. If
057 * the client is in the not authenticated or authenticated state, it enters the
058 * logout on a successful logout.
059 * @return {@code true} if the command was successful,{@code false} if not.
060 * @exception IOException If a network I/O error occurs.
061 */
062 public boolean logout() throws IOException
063 {
064 return doCommand (IMAPCommand.LOGOUT);
065 }
066
067 // --------- commands available in the not-authenticated state
068 // STARTTLS skipped - see IMAPSClient.
069 // AUTHENTICATE skipped - see AuthenticatingIMAPClient.
070
071 /**
072 * Login to the IMAP server with the given username and password. You
073 * must first connect to the server with
074 * {@link org.apache.commons.net.SocketClient#connect connect }
075 * before attempting to login. A login attempt is only valid if
076 * the client is in the NOT_AUTH_STATE.
077 * After logging in, the client enters the AUTH_STATE.
078 * <p>
079 * @param username The account name being logged in to.
080 * @param password The plain text password of the account.
081 * @return True if the login attempt was successful, false if not.
082 * @exception IOException If a network I/O error occurs in the process of
083 * logging in.
084 */
085 public boolean login(String username, String password) throws IOException
086 {
087 if (getState() != IMAP.IMAPState.NOT_AUTH_STATE)
088 {
089 return false;
090 }
091
092 if (!doCommand(IMAPCommand.LOGIN, username + " " + password))
093 {
094 return false;
095 }
096
097 setState(IMAP.IMAPState.AUTH_STATE);
098
099 return true;
100 }
101
102 // --------- commands available in the authenticated state
103
104 /**
105 * Send a SELECT command to the server.
106 * @param mailboxName The mailbox name to select.
107 * @return {@code true} if the command was successful,{@code false} if not.
108 * @exception IOException If a network I/O error occurs.
109 */
110 public boolean select(String mailboxName) throws IOException
111 {
112 return doCommand (IMAPCommand.SELECT, mailboxName);
113 }
114
115 /**
116 * Send an EXAMINE command to the server.
117 * @param mailboxName The mailbox name to examine.
118 * @return {@code true} if the command was successful,{@code false} if not.
119 * @exception IOException If a network I/O error occurs.
120 */
121 public boolean examine(String mailboxName) throws IOException
122 {
123 return doCommand (IMAPCommand.EXAMINE, mailboxName);
124 }
125
126 /**
127 * Send a CREATE command to the server.
128 * @param mailboxName The mailbox name to create.
129 * @return {@code true} if the command was successful,{@code false} if not.
130 * @exception IOException If a network I/O error occurs.
131 */
132 public boolean create(String mailboxName) throws IOException
133 {
134 return doCommand (IMAPCommand.CREATE, mailboxName);
135 }
136
137 /**
138 * Send a DELETE command to the server.
139 * @param mailboxName The mailbox name to delete.
140 * @return {@code true} if the command was successful,{@code false} if not.
141 * @exception IOException If a network I/O error occurs.
142 */
143 public boolean delete(String mailboxName) throws IOException
144 {
145 return doCommand (IMAPCommand.DELETE, mailboxName);
146 }
147
148 /**
149 * Send a RENAME command to the server.
150 * @param oldMailboxName The existing mailbox name to rename.
151 * @param newMailboxName The new mailbox name.
152 * @return {@code true} if the command was successful,{@code false} if not.
153 * @exception IOException If a network I/O error occurs.
154 */
155 public boolean rename(String oldMailboxName, String newMailboxName) throws IOException
156 {
157 return doCommand (IMAPCommand.RENAME, oldMailboxName + " " + newMailboxName);
158 }
159
160 /**
161 * Send a SUBSCRIBE command to the server.
162 * @param mailboxName The mailbox name to subscribe to.
163 * @return {@code true} if the command was successful,{@code false} if not.
164 * @exception IOException If a network I/O error occurs.
165 */
166 public boolean subscribe(String mailboxName) throws IOException
167 {
168 return doCommand (IMAPCommand.SUBSCRIBE, mailboxName);
169 }
170
171 /**
172 * Send a UNSUBSCRIBE command to the server.
173 * @param mailboxName The mailbox name to unsubscribe from.
174 * @return {@code true} if the command was successful,{@code false} if not.
175 * @exception IOException If a network I/O error occurs.
176 */
177 public boolean unsubscribe(String mailboxName) throws IOException
178 {
179 return doCommand (IMAPCommand.UNSUBSCRIBE, mailboxName);
180 }
181
182 /**
183 * Send a LIST command to the server.
184 * @param refName The reference name.
185 * @param mailboxName The mailbox name.
186 * @return {@code true} if the command was successful,{@code false} if not.
187 * @exception IOException If a network I/O error occurs.
188 */
189 public boolean list(String refName, String mailboxName) throws IOException
190 {
191 return doCommand (IMAPCommand.LIST, refName + " " + mailboxName);
192 }
193
194 /**
195 * Send an LSUB command to the server.
196 * @param refName The reference name.
197 * @param mailboxName The mailbox name.
198 * @return {@code true} if the command was successful,{@code false} if not.
199 * @exception IOException If a network I/O error occurs.
200 */
201 public boolean lsub(String refName, String mailboxName) throws IOException
202 {
203 return doCommand (IMAPCommand.LSUB, refName + " " + mailboxName);
204 }
205
206 /**
207 * Send a STATUS command to the server.
208 * @param mailboxName The reference name.
209 * @param itemNames The status data item names.
210 * @return {@code true} if the command was successful,{@code false} if not.
211 * @exception IOException If a network I/O error occurs.
212 */
213 public boolean status(String mailboxName, String[] itemNames) throws IOException
214 {
215 if (itemNames == null || itemNames.length < 1) {
216 throw new IllegalArgumentException("STATUS command requires at least one data item name");
217 }
218
219 StringBuilder sb = new StringBuilder();
220 sb.append(mailboxName);
221
222 sb.append(" (");
223 for ( int i = 0; i < itemNames.length; i++ )
224 {
225 if (i > 0) {
226 sb.append(" ");
227 }
228 sb.append(itemNames[i]);
229 }
230 sb.append(")");
231
232 return doCommand (IMAPCommand.STATUS, sb.toString());
233 }
234
235 /**
236 * Send an APPEND command to the server.
237 * @param mailboxName The mailbox name.
238 * @param flags The flag parenthesized list (optional).
239 * @param datetime The date/time string (optional).
240 * @return {@code true} if the command was successful,{@code false} if not.
241 * @exception IOException If a network I/O error occurs.
242 */
243 public boolean append(String mailboxName, String flags, String datetime) throws IOException
244 {
245 String args = mailboxName;
246 if (flags != null) args += " " + flags;
247 if (datetime != null)
248 {
249 if (datetime.charAt(0) == '{') args += " " + datetime;
250 else args += " {" + datetime + "}";
251 }
252 return doCommand (IMAPCommand.APPEND, args);
253 }
254
255 /**
256 * Send an APPEND command to the server.
257 * @param mailboxName The mailbox name.
258 * @return {@code true} if the command was successful,{@code false} if not.
259 * @exception IOException If a network I/O error occurs.
260 */
261 public boolean append(String mailboxName) throws IOException
262 {
263 return append(mailboxName, null, null);
264 }
265
266 // --------- commands available in the selected state
267
268 /**
269 * Send a CHECK command to the server.
270 * @return {@code true} if the command was successful,{@code false} if not.
271 * @exception IOException If a network I/O error occurs.
272 */
273 public boolean check() throws IOException
274 {
275 return doCommand (IMAPCommand.CHECK);
276 }
277
278 /**
279 * Send a CLOSE command to the server.
280 * @return {@code true} if the command was successful,{@code false} if not.
281 * @exception IOException If a network I/O error occurs.
282 */
283 public boolean close() throws IOException
284 {
285 return doCommand (IMAPCommand.CLOSE);
286 }
287
288 /**
289 * Send an EXPUNGE command to the server.
290 * @return {@code true} if the command was successful,{@code false} if not.
291 * @exception IOException If a network I/O error occurs.
292 */
293 public boolean expunge() throws IOException
294 {
295 return doCommand (IMAPCommand.EXPUNGE);
296 }
297
298 /**
299 * Send a SEARCH command to the server.
300 * @param charset The charset (optional).
301 * @param criteria The search criteria.
302 * @return {@code true} if the command was successful,{@code false} if not.
303 * @exception IOException If a network I/O error occurs.
304 */
305 public boolean search(String charset, String criteria) throws IOException
306 {
307 String args = "";
308 if (charset != null) args += "CHARSET " + charset;
309 args += criteria;
310 return doCommand (IMAPCommand.SEARCH, args);
311 }
312
313 /**
314 * Send a SEARCH command to the server.
315 * @param criteria The search criteria.
316 * @return {@code true} if the command was successful,{@code false} if not.
317 * @exception IOException If a network I/O error occurs.
318 */
319 public boolean search(String criteria) throws IOException
320 {
321 return search(null, criteria);
322 }
323
324 /**
325 * Send a FETCH command to the server.
326 * @param sequenceSet The sequence set to fetch.
327 * @param itemNames The item names for the FETCH command.
328 * @return {@code true} if the command was successful,{@code false} if not.
329 * @exception IOException If a network I/O error occurs.
330 */
331 public boolean fetch(String sequenceSet, String itemNames) throws IOException
332 {
333 return doCommand (IMAPCommand.FETCH, sequenceSet + " " + itemNames);
334 }
335
336 /**
337 * Send a STORE command to the server.
338 * @param sequenceSet The sequence set to store.
339 * @param itemNames The item names for the STORE command.
340 * @param itemValues The item values for the STORE command.
341 * @return {@code true} if the command was successful,{@code false} if not.
342 * @exception IOException If a network I/O error occurs.
343 */
344 public boolean store(String sequenceSet, String itemNames, String itemValues)
345 throws IOException
346 {
347 return doCommand (IMAPCommand.STORE, sequenceSet + " " + itemNames + " " + itemValues);
348 }
349
350 /**
351 * Send a COPY command to the server.
352 * @param sequenceSet The sequence set to fetch.
353 * @param mailboxName The mailbox name.
354 * @return {@code true} if the command was successful,{@code false} if not.
355 * @exception IOException If a network I/O error occurs.
356 */
357 public boolean copy(String sequenceSet, String mailboxName) throws IOException
358 {
359 return doCommand (IMAPCommand.COPY, sequenceSet + " " + mailboxName);
360 }
361
362 /**
363 * Send a UID command to the server.
364 * @param command The command for UID.
365 * @param commandArgs The arguments for the command.
366 * @return {@code true} if the command was successful,{@code false} if not.
367 * @exception IOException If a network I/O error occurs.
368 */
369 public boolean uid(String command, String commandArgs) throws IOException
370 {
371 return doCommand (IMAPCommand.UID, command + " " + commandArgs);
372 }
373
374 /**
375 * The status data items defined in RFC 3501.
376 */
377 public enum STATUS_DATA_ITEMS
378 {
379 /** The number of messages in the mailbox. */
380 MESSAGES,
381 /** The number of messages with the \Recent flag set. */
382 RECENT,
383 /** The next unique identifier value of the mailbox. */
384 UIDNEXT,
385 /** The unique identifier validity value of the mailbox. */
386 UIDVALIDITY,
387 /** The number of messages which do not have the \Seen flag set. */
388 UNSEEN;
389 }
390
391 /**
392 * The search criteria defined in RFC 3501.
393 */
394 public enum SEARCH_CRITERIA
395 {
396 /** All messages in the mailbox. */
397 ALL,
398 /** Messages with the \Answered flag set. */
399 ANSWERED,
400 /**
401 * Messages that contain the specified string in the envelope
402 * structure's BCC field.
403 */
404 BCC,
405 /**
406 * Messages whose internal date (disregarding time and timezone)
407 * is earlier than the specified date.
408 */
409 BEFORE,
410 /**
411 * Messages that contain the specified string in the body of the
412 * message.
413 */
414 BODY,
415 /**
416 * Messages that contain the specified string in the envelope
417 * structure's CC field.
418 */
419 CC,
420 /** Messages with the \Deleted flag set. */
421 DELETED,
422 /** Messages with the \Draft flag set. */
423 DRAFT,
424 /** Messages with the \Flagged flag set. */
425 FLAGGED,
426 /**
427 * Messages that contain the specified string in the envelope
428 * structure's FROM field.
429 */
430 FROM,
431 /**
432 * Messages that have a header with the specified field-name (as
433 * defined in [RFC-2822]) and that contains the specified string
434 * in the text of the header (what comes after the colon). If the
435 * string to search is zero-length, this matches all messages that
436 * have a header line with the specified field-name regardless of
437 * the contents.
438 */
439 HEADER,
440 /** Messages with the specified keyword flag set. */
441 KEYWORD,
442 /**
443 * Messages with an [RFC-2822] size larger than the specified
444 * number of octets.
445 */
446 LARGER,
447 /**
448 * Messages that have the \Recent flag set but not the \Seen flag.
449 * This is functionally equivalent to "(RECENT UNSEEN)".
450 */
451 NEW,
452 /** Messages that do not match the specified search key. */
453 NOT,
454 /**
455 * Messages that do not have the \Recent flag set. This is
456 * functionally equivalent to "NOT RECENT" (as opposed to "NOT
457 * NEW").
458 */
459 OLD,
460 /**
461 * Messages whose internal date (disregarding time and timezone)
462 * is within the specified date.
463 */
464 ON,
465 /** Messages that match either search key. */
466 OR,
467 /** Messages that have the \Recent flag set. */
468 RECENT,
469 /** Messages that have the \Seen flag set. */
470 SEEN,
471 /**
472 * Messages whose [RFC-2822] Date: header (disregarding time and
473 * timezone) is earlier than the specified date.
474 */
475 SENTBEFORE,
476 /**
477 * Messages whose [RFC-2822] Date: header (disregarding time and
478 * timezone) is within the specified date.
479 */
480 SENTON,
481 /**
482 * Messages whose [RFC-2822] Date: header (disregarding time and
483 * timezone) is within or later than the specified date.
484 */
485 SENTSINCE,
486 /**
487 * Messages whose internal date (disregarding time and timezone)
488 * is within or later than the specified date.
489 */
490 SINCE,
491 /**
492 * Messages with an [RFC-2822] size smaller than the specified
493 * number of octets.
494 */
495 SMALLER,
496 /**
497 * Messages that contain the specified string in the envelope
498 * structure's SUBJECT field.
499 */
500 SUBJECT,
501 /**
502 * Messages that contain the specified string in the header or
503 * body of the message.
504 */
505 TEXT,
506 /**
507 * Messages that contain the specified string in the envelope
508 * structure's TO field.
509 */
510 TO,
511 /**
512 * Messages with unique identifiers corresponding to the specified
513 * unique identifier set. Sequence set ranges are permitted.
514 */
515 UID,
516 /** Messages that do not have the \Answered flag set. */
517 UNANSWERED,
518 /** Messages that do not have the \Deleted flag set. */
519 UNDELETED,
520 /** Messages that do not have the \Draft flag set. */
521 UNDRAFT,
522 /** Messages that do not have the \Flagged flag set. */
523 UNFLAGGED,
524 /** Messages that do not have the specified keyword flag set. */
525 UNKEYWORD,
526 /** Messages that do not have the \Seen flag set. */
527 UNSEEN;
528 }
529
530 /**
531 * The message data item names for the FETCH command defined in RFC 3501.
532 */
533 public enum FETCH_ITEM_NAMES
534 {
535 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE). */
536 ALL,
537 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE). */
538 FAST,
539 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY). */
540 FULL,
541 /** Non-extensible form of BODYSTRUCTURE or the text of a particular body section. */
542 BODY,
543 /** The [MIME-IMB] body structure of the message. */
544 BODYSTRUCTURE,
545 /** The envelope structure of the message. */
546 ENVELOPE,
547 /** The flags that are set for this message. */
548 FLAGS,
549 /** The internal date of the message. */
550 INTERNALDATE,
551 /** A prefix for RFC-822 item names. */
552 RFC822,
553 /** The unique identifier for the message. */
554 UID;
555 }
556
557 }
558 /* kate: indent-width 4; replace-tabs on; */