    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
    018package org.apache.commons.net.imap;
    019
    020import java.io.IOException;
    021
    022/**
    023 * The IMAPClient class provides the basic functionalities found in an
    024 * IMAP client.
    025 */
    026public 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; */