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) {
247 args += " " + flags;
248 }
249 if (datetime != null) {
250 if (datetime.charAt(0) == '{') {
251 args += " " + datetime;
252 } else {
253 args += " {" + datetime + "}";
254 }
255 }
256 return doCommand (IMAPCommand.APPEND, args);
257 }
258
259 /**
260 * Send an APPEND command to the server.
261 * @param mailboxName The mailbox name.
262 * @return {@code true} if the command was successful,{@code false} if not.
263 * @exception IOException If a network I/O error occurs.
264 */
265 public boolean append(String mailboxName) throws IOException
266 {
267 return append(mailboxName, null, null);
268 }
269
270 // --------- commands available in the selected state
271
272 /**
273 * Send a CHECK command to the server.
274 * @return {@code true} if the command was successful,{@code false} if not.
275 * @exception IOException If a network I/O error occurs.
276 */
277 public boolean check() throws IOException
278 {
279 return doCommand (IMAPCommand.CHECK);
280 }
281
282 /**
283 * Send a CLOSE command to the server.
284 * @return {@code true} if the command was successful,{@code false} if not.
285 * @exception IOException If a network I/O error occurs.
286 */
287 public boolean close() throws IOException
288 {
289 return doCommand (IMAPCommand.CLOSE);
290 }
291
292 /**
293 * Send an EXPUNGE command to the server.
294 * @return {@code true} if the command was successful,{@code false} if not.
295 * @exception IOException If a network I/O error occurs.
296 */
297 public boolean expunge() throws IOException
298 {
299 return doCommand (IMAPCommand.EXPUNGE);
300 }
301
302 /**
303 * Send a SEARCH command to the server.
304 * @param charset The charset (optional).
305 * @param criteria The search criteria.
306 * @return {@code true} if the command was successful,{@code false} if not.
307 * @exception IOException If a network I/O error occurs.
308 */
309 public boolean search(String charset, String criteria) throws IOException
310 {
311 String args = "";
312 if (charset != null) {
313 args += "CHARSET " + charset;
314 }
315 args += criteria;
316 return doCommand (IMAPCommand.SEARCH, args);
317 }
318
319 /**
320 * Send a SEARCH command to the server.
321 * @param criteria The search criteria.
322 * @return {@code true} if the command was successful,{@code false} if not.
323 * @exception IOException If a network I/O error occurs.
324 */
325 public boolean search(String criteria) throws IOException
326 {
327 return search(null, criteria);
328 }
329
330 /**
331 * Send a FETCH command to the server.
332 * @param sequenceSet The sequence set to fetch.
333 * @param itemNames The item names for the FETCH command.
334 * @return {@code true} if the command was successful,{@code false} if not.
335 * @exception IOException If a network I/O error occurs.
336 */
337 public boolean fetch(String sequenceSet, String itemNames) throws IOException
338 {
339 return doCommand (IMAPCommand.FETCH, sequenceSet + " " + itemNames);
340 }
341
342 /**
343 * Send a STORE command to the server.
344 * @param sequenceSet The sequence set to store.
345 * @param itemNames The item names for the STORE command.
346 * @param itemValues The item values for the STORE command.
347 * @return {@code true} if the command was successful,{@code false} if not.
348 * @exception IOException If a network I/O error occurs.
349 */
350 public boolean store(String sequenceSet, String itemNames, String itemValues)
351 throws IOException
352 {
353 return doCommand (IMAPCommand.STORE, sequenceSet + " " + itemNames + " " + itemValues);
354 }
355
356 /**
357 * Send a COPY command to the server.
358 * @param sequenceSet The sequence set to fetch.
359 * @param mailboxName The mailbox name.
360 * @return {@code true} if the command was successful,{@code false} if not.
361 * @exception IOException If a network I/O error occurs.
362 */
363 public boolean copy(String sequenceSet, String mailboxName) throws IOException
364 {
365 return doCommand (IMAPCommand.COPY, sequenceSet + " " + mailboxName);
366 }
367
368 /**
369 * Send a UID command to the server.
370 * @param command The command for UID.
371 * @param commandArgs The arguments for the command.
372 * @return {@code true} if the command was successful,{@code false} if not.
373 * @exception IOException If a network I/O error occurs.
374 */
375 public boolean uid(String command, String commandArgs) throws IOException
376 {
377 return doCommand (IMAPCommand.UID, command + " " + commandArgs);
378 }
379
380 /**
381 * The status data items defined in RFC 3501.
382 */
383 public enum STATUS_DATA_ITEMS
384 {
385 /** The number of messages in the mailbox. */
386 MESSAGES,
387 /** The number of messages with the \Recent flag set. */
388 RECENT,
389 /** The next unique identifier value of the mailbox. */
390 UIDNEXT,
391 /** The unique identifier validity value of the mailbox. */
392 UIDVALIDITY,
393 /** The number of messages which do not have the \Seen flag set. */
394 UNSEEN;
395 }
396
397 /**
398 * The search criteria defined in RFC 3501.
399 */
400 public enum SEARCH_CRITERIA
401 {
402 /** All messages in the mailbox. */
403 ALL,
404 /** Messages with the \Answered flag set. */
405 ANSWERED,
406 /**
407 * Messages that contain the specified string in the envelope
408 * structure's BCC field.
409 */
410 BCC,
411 /**
412 * Messages whose internal date (disregarding time and timezone)
413 * is earlier than the specified date.
414 */
415 BEFORE,
416 /**
417 * Messages that contain the specified string in the body of the
418 * message.
419 */
420 BODY,
421 /**
422 * Messages that contain the specified string in the envelope
423 * structure's CC field.
424 */
425 CC,
426 /** Messages with the \Deleted flag set. */
427 DELETED,
428 /** Messages with the \Draft flag set. */
429 DRAFT,
430 /** Messages with the \Flagged flag set. */
431 FLAGGED,
432 /**
433 * Messages that contain the specified string in the envelope
434 * structure's FROM field.
435 */
436 FROM,
437 /**
438 * Messages that have a header with the specified field-name (as
439 * defined in [RFC-2822]) and that contains the specified string
440 * in the text of the header (what comes after the colon). If the
441 * string to search is zero-length, this matches all messages that
442 * have a header line with the specified field-name regardless of
443 * the contents.
444 */
445 HEADER,
446 /** Messages with the specified keyword flag set. */
447 KEYWORD,
448 /**
449 * Messages with an [RFC-2822] size larger than the specified
450 * number of octets.
451 */
452 LARGER,
453 /**
454 * Messages that have the \Recent flag set but not the \Seen flag.
455 * This is functionally equivalent to "(RECENT UNSEEN)".
456 */
457 NEW,
458 /** Messages that do not match the specified search key. */
459 NOT,
460 /**
461 * Messages that do not have the \Recent flag set. This is
462 * functionally equivalent to "NOT RECENT" (as opposed to "NOT
463 * NEW").
464 */
465 OLD,
466 /**
467 * Messages whose internal date (disregarding time and timezone)
468 * is within the specified date.
469 */
470 ON,
471 /** Messages that match either search key. */
472 OR,
473 /** Messages that have the \Recent flag set. */
474 RECENT,
475 /** Messages that have the \Seen flag set. */
476 SEEN,
477 /**
478 * Messages whose [RFC-2822] Date: header (disregarding time and
479 * timezone) is earlier than the specified date.
480 */
481 SENTBEFORE,
482 /**
483 * Messages whose [RFC-2822] Date: header (disregarding time and
484 * timezone) is within the specified date.
485 */
486 SENTON,
487 /**
488 * Messages whose [RFC-2822] Date: header (disregarding time and
489 * timezone) is within or later than the specified date.
490 */
491 SENTSINCE,
492 /**
493 * Messages whose internal date (disregarding time and timezone)
494 * is within or later than the specified date.
495 */
496 SINCE,
497 /**
498 * Messages with an [RFC-2822] size smaller than the specified
499 * number of octets.
500 */
501 SMALLER,
502 /**
503 * Messages that contain the specified string in the envelope
504 * structure's SUBJECT field.
505 */
506 SUBJECT,
507 /**
508 * Messages that contain the specified string in the header or
509 * body of the message.
510 */
511 TEXT,
512 /**
513 * Messages that contain the specified string in the envelope
514 * structure's TO field.
515 */
516 TO,
517 /**
518 * Messages with unique identifiers corresponding to the specified
519 * unique identifier set. Sequence set ranges are permitted.
520 */
521 UID,
522 /** Messages that do not have the \Answered flag set. */
523 UNANSWERED,
524 /** Messages that do not have the \Deleted flag set. */
525 UNDELETED,
526 /** Messages that do not have the \Draft flag set. */
527 UNDRAFT,
528 /** Messages that do not have the \Flagged flag set. */
529 UNFLAGGED,
530 /** Messages that do not have the specified keyword flag set. */
531 UNKEYWORD,
532 /** Messages that do not have the \Seen flag set. */
533 UNSEEN;
534 }
535
536 /**
537 * The message data item names for the FETCH command defined in RFC 3501.
538 */
539 public enum FETCH_ITEM_NAMES
540 {
541 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE). */
542 ALL,
543 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE). */
544 FAST,
545 /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY). */
546 FULL,
547 /** Non-extensible form of BODYSTRUCTURE or the text of a particular body section. */
548 BODY,
549 /** The [MIME-IMB] body structure of the message. */
550 BODYSTRUCTURE,
551 /** The envelope structure of the message. */
552 ENVELOPE,
553 /** The flags that are set for this message. */
554 FLAGS,
555 /** The internal date of the message. */
556 INTERNALDATE,
557 /** A prefix for RFC-822 item names. */
558 RFC822,
559 /** The unique identifier for the message. */
560 UID;
561 }
562
563 }
564 /* kate: indent-width 4; replace-tabs on; */