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; */