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