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