| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.commons.net.imap; |
| |
| import java.io.IOException; |
| |
| /** |
| * The IMAPClient class provides the basic functionalities found in an |
| * IMAP client. |
| */ |
| public class IMAPClient extends IMAP |
| { |
| |
| private static final char DQUOTE = '"'; |
| private static final String DQUOTE_S = "\""; |
| |
| // --------- commands available in all states |
| |
| /** |
| * Send a CAPABILITY command to the server. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs |
| */ |
| public boolean capability() throws IOException |
| { |
| return doCommand (IMAPCommand.CAPABILITY); |
| } |
| |
| /** |
| * Send a NOOP command to the server. This is useful for keeping |
| * a connection alive since most IMAP servers will timeout after 10 |
| * minutes of inactivity. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean noop() throws IOException |
| { |
| return doCommand (IMAPCommand.NOOP); |
| } |
| |
| /** |
| * Send a LOGOUT command to the server. To fully disconnect from the server |
| * you must call disconnect(). |
| * A logout attempt is valid in any state. If |
| * the client is in the not authenticated or authenticated state, it enters the |
| * logout on a successful logout. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean logout() throws IOException |
| { |
| return doCommand (IMAPCommand.LOGOUT); |
| } |
| |
| // --------- commands available in the not-authenticated state |
| // STARTTLS skipped - see IMAPSClient. |
| // AUTHENTICATE skipped - see AuthenticatingIMAPClient. |
| |
| /** |
| * Login to the IMAP server with the given username and password. You |
| * must first connect to the server with |
| * {@link org.apache.commons.net.SocketClient#connect connect } |
| * before attempting to login. A login attempt is only valid if |
| * the client is in the NOT_AUTH_STATE. |
| * After logging in, the client enters the AUTH_STATE. |
| * |
| * @param username The account name being logged in to. |
| * @param password The plain text password of the account. |
| * @return True if the login attempt was successful, false if not. |
| * @throws IOException If a network I/O error occurs in the process of |
| * logging in. |
| */ |
| public boolean login(String username, String password) throws IOException |
| { |
| if (getState() != IMAP.IMAPState.NOT_AUTH_STATE) |
| { |
| return false; |
| } |
| |
| if (!doCommand(IMAPCommand.LOGIN, username + " " + password)) |
| { |
| return false; |
| } |
| |
| setState(IMAP.IMAPState.AUTH_STATE); |
| |
| return true; |
| } |
| |
| // --------- commands available in the authenticated state |
| |
| /** |
| * Send a SELECT command to the server. |
| * @param mailboxName The mailbox name to select. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean select(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.SELECT, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send an EXAMINE command to the server. |
| * @param mailboxName The mailbox name to examine. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean examine(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.EXAMINE, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a CREATE command to the server. |
| * @param mailboxName The mailbox name to create. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean create(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.CREATE, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a DELETE command to the server. |
| * @param mailboxName The mailbox name to delete. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean delete(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.DELETE, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a RENAME command to the server. |
| * @param oldMailboxName The existing mailbox name to rename. |
| * @param newMailboxName The new mailbox name. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean rename(String oldMailboxName, String newMailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.RENAME, quoteMailboxName(oldMailboxName) + " " + quoteMailboxName(newMailboxName)); |
| } |
| |
| /** |
| * Send a SUBSCRIBE command to the server. |
| * @param mailboxName The mailbox name to subscribe to. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean subscribe(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.SUBSCRIBE, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a UNSUBSCRIBE command to the server. |
| * @param mailboxName The mailbox name to unsubscribe from. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean unsubscribe(String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.UNSUBSCRIBE, quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a LIST command to the server. |
| * Quotes the parameters if necessary. |
| * @param refName The reference name |
| * If empty, indicates that the mailbox name is interpreted as by SELECT. |
| * @param mailboxName The mailbox name. |
| * If empty, this is a special request to |
| * return the hierarchy delimiter and the root name of the name given |
| * in the reference |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean list(String refName, String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.LIST, quoteMailboxName(refName) + " " + quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send an LSUB command to the server. |
| * Quotes the parameters if necessary. |
| * @param refName The reference name. |
| * @param mailboxName The mailbox name. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean lsub(String refName, String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.LSUB, quoteMailboxName(refName) + " " + quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a STATUS command to the server. |
| * @param mailboxName The reference name. |
| * @param itemNames The status data item names. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean status(String mailboxName, String[] itemNames) throws IOException |
| { |
| if (itemNames == null || itemNames.length < 1) { |
| throw new IllegalArgumentException("STATUS command requires at least one data item name"); |
| } |
| |
| StringBuilder sb = new StringBuilder(); |
| sb.append(quoteMailboxName(mailboxName)); |
| |
| sb.append(" ("); |
| for ( int i = 0; i < itemNames.length; i++ ) |
| { |
| if (i > 0) { |
| sb.append(" "); |
| } |
| sb.append(itemNames[i]); |
| } |
| sb.append(")"); |
| |
| return doCommand (IMAPCommand.STATUS, sb.toString()); |
| } |
| |
| /** |
| * Send an APPEND command to the server. |
| * @param mailboxName The mailbox name. |
| * @param flags The flag parenthesized list (optional). |
| * @param datetime The date/time string (optional). |
| * @param message The message to append. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| * @since 3.4 |
| */ |
| public boolean append(String mailboxName, String flags, String datetime, String message) throws IOException |
| { |
| StringBuilder args = new StringBuilder(quoteMailboxName(mailboxName)); |
| if (flags != null) { |
| args.append(" ").append(flags); |
| } |
| if (datetime != null) { |
| args.append(" "); |
| if (datetime.charAt(0) == DQUOTE) { |
| args.append(datetime); |
| } else { |
| args.append(DQUOTE).append(datetime).append(DQUOTE); |
| } |
| } |
| args.append(" "); |
| // String literal (probably not used much - it at all) |
| if (message.startsWith(DQUOTE_S) && message.endsWith(DQUOTE_S)) { |
| args.append(message); |
| return doCommand (IMAPCommand.APPEND, args.toString()); |
| } |
| args.append('{').append(message.length()).append('}'); // length of message |
| final int status = sendCommand(IMAPCommand.APPEND, args.toString()); |
| return IMAPReply.isContinuation(status) // expecting continuation response |
| && IMAPReply.isSuccess(sendData(message)); // if so, send the data |
| } |
| |
| /** |
| * Send an APPEND command to the server. |
| * @param mailboxName The mailbox name. |
| * @param flags The flag parenthesized list (optional). |
| * @param datetime The date/time string (optional). |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| * @deprecated (3.4) Does not work; the message body is not optional. |
| * Use {@link #append(String, String, String, String)} instead. |
| */ |
| @Deprecated |
| public boolean append(String mailboxName, String flags, String datetime) throws IOException |
| { |
| String args = mailboxName; |
| if (flags != null) { |
| args += " " + flags; |
| } |
| if (datetime != null) { |
| if (datetime.charAt(0) == '{') { |
| args += " " + datetime; |
| } else { |
| args += " {" + datetime + "}"; |
| } |
| } |
| return doCommand (IMAPCommand.APPEND, args); |
| } |
| |
| /** |
| * Send an APPEND command to the server. |
| * @param mailboxName The mailbox name. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| * @deprecated (3.4) Does not work; the message body is not optional. |
| * Use {@link #append(String, String, String, String)} instead. |
| */ |
| @Deprecated |
| public boolean append(String mailboxName) throws IOException |
| { |
| return append(mailboxName, null, null); |
| } |
| |
| // --------- commands available in the selected state |
| |
| /** |
| * Send a CHECK command to the server. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean check() throws IOException |
| { |
| return doCommand (IMAPCommand.CHECK); |
| } |
| |
| /** |
| * Send a CLOSE command to the server. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean close() throws IOException |
| { |
| return doCommand (IMAPCommand.CLOSE); |
| } |
| |
| /** |
| * Send an EXPUNGE command to the server. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean expunge() throws IOException |
| { |
| return doCommand (IMAPCommand.EXPUNGE); |
| } |
| |
| /** |
| * Send a SEARCH command to the server. |
| * @param charset The charset (optional). |
| * @param criteria The search criteria. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean search(String charset, String criteria) throws IOException |
| { |
| String args = ""; |
| if (charset != null) { |
| args += "CHARSET " + charset; |
| } |
| args += criteria; |
| return doCommand (IMAPCommand.SEARCH, args); |
| } |
| |
| /** |
| * Send a SEARCH command to the server. |
| * @param criteria The search criteria. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean search(String criteria) throws IOException |
| { |
| return search(null, criteria); |
| } |
| |
| /** |
| * Send a FETCH command to the server. |
| * |
| * @param sequenceSet The sequence set to fetch (e.g. 1:4,6,11,100:*) |
| * @param itemNames The item names for the FETCH command. (e.g. BODY.PEEK[HEADER.FIELDS (SUBJECT)]) |
| * If multiple item names are requested, these must be enclosed in parentheses, e.g. "(UID FLAGS BODY.PEEK[])" |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| * @see #getReplyString() |
| * @see #getReplyStrings() |
| */ |
| public boolean fetch(String sequenceSet, String itemNames) throws IOException |
| { |
| return doCommand (IMAPCommand.FETCH, sequenceSet + " " + itemNames); |
| } |
| |
| /** |
| * Send a STORE command to the server. |
| * @param sequenceSet The sequence set to update (e.g. 2:5) |
| * @param itemNames The item name for the STORE command (i.e. [+|-]FLAGS[.SILENT]) |
| * @param itemValues The item values for the STORE command. (e.g. (\Deleted) ) |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean store(String sequenceSet, String itemNames, String itemValues) |
| throws IOException |
| { |
| return doCommand (IMAPCommand.STORE, sequenceSet + " " + itemNames + " " + itemValues); |
| } |
| |
| /** |
| * Send a COPY command to the server. |
| * @param sequenceSet The sequence set to fetch. |
| * @param mailboxName The mailbox name. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean copy(String sequenceSet, String mailboxName) throws IOException |
| { |
| return doCommand (IMAPCommand.COPY, sequenceSet + " " + quoteMailboxName(mailboxName)); |
| } |
| |
| /** |
| * Send a UID command to the server. |
| * @param command The command for UID. |
| * @param commandArgs The arguments for the command. |
| * @return {@code true} if the command was successful,{@code false} if not. |
| * @throws IOException If a network I/O error occurs. |
| */ |
| public boolean uid(String command, String commandArgs) throws IOException |
| { |
| return doCommand (IMAPCommand.UID, command + " " + commandArgs); |
| } |
| |
| /** |
| * The status data items defined in RFC 3501. |
| */ |
| public enum STATUS_DATA_ITEMS |
| { |
| /** The number of messages in the mailbox. */ |
| MESSAGES, |
| /** The number of messages with the \Recent flag set. */ |
| RECENT, |
| /** The next unique identifier value of the mailbox. */ |
| UIDNEXT, |
| /** The unique identifier validity value of the mailbox. */ |
| UIDVALIDITY, |
| /** The number of messages which do not have the \Seen flag set. */ |
| UNSEEN; |
| } |
| |
| /** |
| * The search criteria defined in RFC 3501. |
| */ |
| public enum SEARCH_CRITERIA |
| { |
| /** All messages in the mailbox. */ |
| ALL, |
| /** Messages with the \Answered flag set. */ |
| ANSWERED, |
| /** |
| * Messages that contain the specified string in the envelope |
| * structure's BCC field. |
| */ |
| BCC, |
| /** |
| * Messages whose internal date (disregarding time and timezone) |
| * is earlier than the specified date. |
| */ |
| BEFORE, |
| /** |
| * Messages that contain the specified string in the body of the |
| * message. |
| */ |
| BODY, |
| /** |
| * Messages that contain the specified string in the envelope |
| * structure's CC field. |
| */ |
| CC, |
| /** Messages with the \Deleted flag set. */ |
| DELETED, |
| /** Messages with the \Draft flag set. */ |
| DRAFT, |
| /** Messages with the \Flagged flag set. */ |
| FLAGGED, |
| /** |
| * Messages that contain the specified string in the envelope |
| * structure's FROM field. |
| */ |
| FROM, |
| /** |
| * Messages that have a header with the specified field-name (as |
| * defined in [RFC-2822]) and that contains the specified string |
| * in the text of the header (what comes after the colon). If the |
| * string to search is zero-length, this matches all messages that |
| * have a header line with the specified field-name regardless of |
| * the contents. |
| */ |
| HEADER, |
| /** Messages with the specified keyword flag set. */ |
| KEYWORD, |
| /** |
| * Messages with an [RFC-2822] size larger than the specified |
| * number of octets. |
| */ |
| LARGER, |
| /** |
| * Messages that have the \Recent flag set but not the \Seen flag. |
| * This is functionally equivalent to "(RECENT UNSEEN)". |
| */ |
| NEW, |
| /** Messages that do not match the specified search key. */ |
| NOT, |
| /** |
| * Messages that do not have the \Recent flag set. This is |
| * functionally equivalent to "NOT RECENT" (as opposed to "NOT |
| * NEW"). |
| */ |
| OLD, |
| /** |
| * Messages whose internal date (disregarding time and timezone) |
| * is within the specified date. |
| */ |
| ON, |
| /** Messages that match either search key. */ |
| OR, |
| /** Messages that have the \Recent flag set. */ |
| RECENT, |
| /** Messages that have the \Seen flag set. */ |
| SEEN, |
| /** |
| * Messages whose [RFC-2822] Date: header (disregarding time and |
| * timezone) is earlier than the specified date. |
| */ |
| SENTBEFORE, |
| /** |
| * Messages whose [RFC-2822] Date: header (disregarding time and |
| * timezone) is within the specified date. |
| */ |
| SENTON, |
| /** |
| * Messages whose [RFC-2822] Date: header (disregarding time and |
| * timezone) is within or later than the specified date. |
| */ |
| SENTSINCE, |
| /** |
| * Messages whose internal date (disregarding time and timezone) |
| * is within or later than the specified date. |
| */ |
| SINCE, |
| /** |
| * Messages with an [RFC-2822] size smaller than the specified |
| * number of octets. |
| */ |
| SMALLER, |
| /** |
| * Messages that contain the specified string in the envelope |
| * structure's SUBJECT field. |
| */ |
| SUBJECT, |
| /** |
| * Messages that contain the specified string in the header or |
| * body of the message. |
| */ |
| TEXT, |
| /** |
| * Messages that contain the specified string in the envelope |
| * structure's TO field. |
| */ |
| TO, |
| /** |
| * Messages with unique identifiers corresponding to the specified |
| * unique identifier set. Sequence set ranges are permitted. |
| */ |
| UID, |
| /** Messages that do not have the \Answered flag set. */ |
| UNANSWERED, |
| /** Messages that do not have the \Deleted flag set. */ |
| UNDELETED, |
| /** Messages that do not have the \Draft flag set. */ |
| UNDRAFT, |
| /** Messages that do not have the \Flagged flag set. */ |
| UNFLAGGED, |
| /** Messages that do not have the specified keyword flag set. */ |
| UNKEYWORD, |
| /** Messages that do not have the \Seen flag set. */ |
| UNSEEN; |
| } |
| |
| /** |
| * The message data item names for the FETCH command defined in RFC 3501. |
| */ |
| public enum FETCH_ITEM_NAMES |
| { |
| /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE). */ |
| ALL, |
| /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE). */ |
| FAST, |
| /** Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY). */ |
| FULL, |
| /** Non-extensible form of BODYSTRUCTURE or the text of a particular body section. */ |
| BODY, |
| /** The [MIME-IMB] body structure of the message. */ |
| BODYSTRUCTURE, |
| /** The envelope structure of the message. */ |
| ENVELOPE, |
| /** The flags that are set for this message. */ |
| FLAGS, |
| /** The internal date of the message. */ |
| INTERNALDATE, |
| /** A prefix for RFC-822 item names. */ |
| RFC822, |
| /** The unique identifier for the message. */ |
| UID; |
| } |
| |
| } |
| /* kate: indent-width 4; replace-tabs on; */ |