Home | History | Annotate | Download | only in mail
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.email.mail;
     18 
     19 
     20 public abstract class Folder {
     21     public enum OpenMode {
     22         READ_WRITE, READ_ONLY,
     23     }
     24 
     25     public enum FolderType {
     26         HOLDS_FOLDERS, HOLDS_MESSAGES,
     27     }
     28 
     29     /**
     30      * Identifiers of "special" folders.
     31      */
     32     public enum FolderRole {
     33         INBOX,      // NOTE:  The folder's name must be INBOX
     34         TRASH,
     35         SENT,
     36         DRAFTS,
     37 
     38         OUTBOX,     // Local folders only - not used in remote Stores
     39         OTHER,      // this folder has no specific role
     40         UNKNOWN     // the role of this folder is unknown
     41     }
     42 
     43     /**
     44      * Callback for each message retrieval.
     45      *
     46      * Not all {@link Folder} implementation won't call it.
     47      * (Currently {@link com.android.email.mail.store.LocalStore.LocalFolder} won't.)
     48      */
     49     public interface MessageRetrievalListener {
     50         public void messageRetrieved(Message message);
     51     }
     52 
     53     /**
     54      * Forces an open of the MailProvider. If the provider is already open this
     55      * function returns without doing anything.
     56      *
     57      * @param mode READ_ONLY or READ_WRITE
     58      * @param callbacks Pointer to callbacks class.  This may be used by the folder between this
     59      * time and when close() is called.  This is only used for remote stores - should be null
     60      * for LocalStore.LocalFolder.
     61      */
     62     public abstract void open(OpenMode mode, PersistentDataCallbacks callbacks)
     63             throws MessagingException;
     64 
     65     /**
     66      * Forces a close of the MailProvider. Any further access will attempt to
     67      * reopen the MailProvider.
     68      *
     69      * @param expunge If true all deleted messages will be expunged.
     70      */
     71     public abstract void close(boolean expunge) throws MessagingException;
     72 
     73     /**
     74      * @return True if further commands are not expected to have to open the
     75      *         connection.
     76      */
     77     // TODO not used, get rid of this - it's a transport function
     78     public abstract boolean isOpen();
     79 
     80     /**
     81      * Get the mode the folder was opened with. This may be different than the mode the open
     82      * was requested with.
     83      * @return
     84      */
     85     public abstract OpenMode getMode() throws MessagingException;
     86 
     87     /**
     88      * Reports if the Store is able to create folders of the given type.
     89      * Does not actually attempt to create a folder.
     90      * @param type
     91      * @return true if can create, false if cannot create
     92      */
     93     public abstract boolean canCreate(FolderType type);
     94 
     95     /**
     96      * Attempt to create the given folder remotely using the given type.
     97      * @param type
     98      * @return true if created, false if cannot create (e.g. server side)
     99      */
    100     public abstract boolean create(FolderType type) throws MessagingException;
    101 
    102     public abstract boolean exists() throws MessagingException;
    103 
    104     /**
    105      * @return A count of the messages in the selected folder.
    106      */
    107     public abstract int getMessageCount() throws MessagingException;
    108 
    109     public abstract int getUnreadMessageCount() throws MessagingException;
    110 
    111     public abstract Message getMessage(String uid) throws MessagingException;
    112 
    113     public abstract Message[] getMessages(int start, int end, MessageRetrievalListener listener)
    114             throws MessagingException;
    115 
    116     /**
    117      * Fetches the given list of messages. The specified listener is notified as
    118      * each fetch completes. Messages are downloaded as (as) lightweight (as
    119      * possible) objects to be filled in with later requests. In most cases this
    120      * means that only the UID is downloaded.
    121      *
    122      * @param uids
    123      * @param listener
    124      */
    125     public abstract Message[] getMessages(MessageRetrievalListener listener)
    126             throws MessagingException;
    127 
    128     public abstract Message[] getMessages(String[] uids, MessageRetrievalListener listener)
    129             throws MessagingException;
    130 
    131     /**
    132      * Return a set of messages based on the state of the flags.
    133      * Note: Not typically implemented in remote stores, so not abstract.
    134      *
    135      * @param setFlags The flags that should be set for a message to be selected (can be null)
    136      * @param clearFlags The flags that should be clear for a message to be selected (can be null)
    137      * @param listener
    138      * @return A list of messages matching the desired flag states.
    139      * @throws MessagingException
    140      */
    141     public Message[] getMessages(Flag[] setFlags, Flag[] clearFlags,
    142             MessageRetrievalListener listener) throws MessagingException {
    143         throw new MessagingException("Not implemented");
    144     }
    145 
    146     public abstract void appendMessages(Message[] messages) throws MessagingException;
    147 
    148     public abstract void copyMessages(Message[] msgs, Folder folder,
    149             MessageUpdateCallbacks callbacks) throws MessagingException;
    150 
    151     public abstract void setFlags(Message[] messages, Flag[] flags, boolean value)
    152             throws MessagingException;
    153 
    154     public abstract Message[] expunge() throws MessagingException;
    155 
    156     public abstract void fetch(Message[] messages, FetchProfile fp,
    157             MessageRetrievalListener listener) throws MessagingException;
    158 
    159     public abstract void delete(boolean recurse) throws MessagingException;
    160 
    161     public abstract String getName();
    162 
    163     public abstract Flag[] getPermanentFlags() throws MessagingException;
    164 
    165     /**
    166      * This method returns a string identifying the name of a "role" folder
    167      * (such as inbox, draft, sent, or trash).  Stores that do not implement this
    168      * feature can be used - the account UI will provide default strings.  To
    169      * let the server identify specific folder roles, simply override this method.
    170      *
    171      * @return The server- or protocol- specific role for this folder.  If some roles are known
    172      * but this is not one of them, return FolderRole.OTHER.  If roles are unsupported here,
    173      * return FolderRole.UNKNOWN.
    174      */
    175     public FolderRole getRole() {
    176         return FolderRole.UNKNOWN;
    177     }
    178 
    179     /**
    180      * This function will be called after the messaging controller has called
    181      * getPersonalNamespaces() and has created a matching LocalFolder object.  This can
    182      * be used as a trigger for the folder to write back any folder-specific persistent data using
    183      * callbacks.
    184      *
    185      * This is not abstract because most folders do not require this functionality and do not
    186      * need to implement it.
    187      */
    188     @SuppressWarnings("unused")
    189     public void localFolderSetupComplete(Folder localFolder) throws MessagingException {
    190         // Do nothing - return immediately
    191     }
    192 
    193     /**
    194      * Create an empty message of the appropriate type for the Folder.
    195      */
    196     public abstract Message createMessage(String uid) throws MessagingException;
    197 
    198     /**
    199      * Callback interface by which a Folder can read and write persistent data.
    200      * TODO This needs to be made more generic & flexible
    201      */
    202     public interface PersistentDataCallbacks {
    203 
    204         /**
    205          * Provides keyed storage of strings.  Should be used for per-folder data.  Do not use for
    206          * per-message data.
    207          * @param key identifier for the data (e.g. "sync.key" or "folder.id")
    208          * @param value Data to persist.  All data must be encoded into a string,
    209          * so use base64 or some other encoding if necessary.
    210          */
    211         public void setPersistentString(String key, String value);
    212 
    213         /**
    214          * @param key identifier for the data of interest
    215          * @return the data saved by the Folder, or defaultValue if never set.
    216          */
    217         public String getPersistentString(String key, String defaultValue);
    218 
    219         /**
    220          * In a single transaction:  Set a key/value pair for the folder, and bulk set or clear
    221          * message flags.  Typically used at the beginning or conclusion of a bulk sync operation.
    222          *
    223          * @param key if non-null, the transaction will set this folder persistent value
    224          * @param value the value that will be stored for the key
    225          * @param setFlags if non-null, flag(s) will be set for all messages in the folder
    226          * @param clearFlags if non-null, flag(s) will be cleared for all messages in the folder
    227          */
    228         public void setPersistentStringAndMessageFlags(String key, String value,
    229                 Flag[] setFlags, Flag[] clearFlags) throws MessagingException;
    230     }
    231 
    232     /**
    233      * Callback interface by which a folder can report UID changes caused by certain operations.
    234      */
    235     public interface MessageUpdateCallbacks {
    236         /**
    237          * The operation caused the message's UID to change
    238          * @param message The message for which the UID changed
    239          * @param newUid The new UID for the message
    240          */
    241         public void onMessageUidChange(Message message, String newUid) throws MessagingException;
    242 
    243         /**
    244          * The operation could not be completed because the message doesn't exist
    245          * (for example, it was already deleted from the server side.)
    246          * @param message The message that does not exist
    247          * @throws MessagingException
    248          */
    249         public void onMessageNotFound(Message message) throws MessagingException;
    250     }
    251 
    252     @Override
    253     public String toString() {
    254         return getName();
    255     }
    256 }
    257