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