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