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.emailcommon.mail;
18 
19 import android.content.Context;
20 
21 import com.android.emailcommon.service.SearchParams;
22 import com.google.common.annotations.VisibleForTesting;
23 
24 
25 public abstract class Folder {
26     public enum OpenMode {
27         READ_WRITE, READ_ONLY,
28     }
29 
30     public enum FolderType {
31         HOLDS_FOLDERS, HOLDS_MESSAGES,
32     }
33 
34     /**
35      * Identifiers of "special" folders.
36      */
37     public enum FolderRole {
38         INBOX,      // NOTE:  The folder's name must be INBOX
39         TRASH,
40         SENT,
41         DRAFTS,
42 
43         OUTBOX,     // Local folders only - not used in remote Stores
44         OTHER,      // this folder has no specific role
45         UNKNOWN     // the role of this folder is unknown
46     }
47 
48     /**
49      * Callback for each message retrieval.
50      *
51      * Not all {@link Folder} implementations may invoke it.
52      */
53     public interface MessageRetrievalListener {
messageRetrieved(Message message)54         public void messageRetrieved(Message message);
loadAttachmentProgress(int progress)55         public void loadAttachmentProgress(int progress);
56     }
57 
58     /**
59      * Forces an open of the MailProvider. If the provider is already open this
60      * function returns without doing anything.
61      *
62      * @param mode READ_ONLY or READ_WRITE
63      * @param callbacks Pointer to callbacks class.  This may be used by the folder between this
64      * time and when close() is called.  This is only used for remote stores - should be null
65      * for LocalStore.LocalFolder.
66      */
open(OpenMode mode)67     public abstract void open(OpenMode mode)
68             throws MessagingException;
69 
70     /**
71      * Forces a close of the MailProvider. Any further access will attempt to
72      * reopen the MailProvider.
73      *
74      * @param expunge If true all deleted messages will be expunged.
75      */
close(boolean expunge)76     public abstract void close(boolean expunge);
77 
78     /**
79      * @return True if further commands are not expected to have to open the
80      *         connection.
81      */
82     @VisibleForTesting
isOpen()83     public abstract boolean isOpen();
84 
85     /**
86      * Returns the mode the folder was opened with. This may be different than the mode the open
87      * was requested with.
88      */
getMode()89     public abstract OpenMode getMode() throws MessagingException;
90 
91     /**
92      * Reports if the Store is able to create folders of the given type.
93      * Does not actually attempt to create a folder.
94      * @param type
95      * @return true if can create, false if cannot create
96      */
canCreate(FolderType type)97     public abstract boolean canCreate(FolderType type);
98 
99     /**
100      * Attempt to create the given folder remotely using the given type.
101      * @return true if created, false if cannot create (e.g. server side)
102      */
create(FolderType type)103     public abstract boolean create(FolderType type) throws MessagingException;
104 
exists()105     public abstract boolean exists() throws MessagingException;
106 
107     /**
108      * Returns the number of messages in the selected folder.
109      */
getMessageCount()110     public abstract int getMessageCount() throws MessagingException;
111 
getUnreadMessageCount()112     public abstract int getUnreadMessageCount() throws MessagingException;
113 
getMessage(String uid)114     public abstract Message getMessage(String uid) 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      */
getMessages(int start, int end, MessageRetrievalListener listener)122     public abstract Message[] getMessages(int start, int end, MessageRetrievalListener listener)
123             throws MessagingException;
124 
getMessages(long startDate, long endDate, MessageRetrievalListener listener)125     public abstract Message[] getMessages(long startDate, long endDate, MessageRetrievalListener listener)
126             throws MessagingException;
127 
getMessages(SearchParams params,MessageRetrievalListener listener)128     public abstract Message[] getMessages(SearchParams params,MessageRetrievalListener listener)
129             throws MessagingException;
130 
getMessages(String[] uids, MessageRetrievalListener listener)131     public abstract Message[] getMessages(String[] uids, MessageRetrievalListener listener)
132             throws MessagingException;
133 
134     /**
135      * Return a set of messages based on the state of the flags.
136      * Note: Not typically implemented in remote stores, so not abstract.
137      *
138      * @param setFlags The flags that should be set for a message to be selected (can be null)
139      * @param clearFlags The flags that should be clear for a message to be selected (can be null)
140      * @param listener
141      * @return A list of messages matching the desired flag states.
142      * @throws MessagingException
143      */
getMessages(Flag[] setFlags, Flag[] clearFlags, MessageRetrievalListener listener)144     public Message[] getMessages(Flag[] setFlags, Flag[] clearFlags,
145             MessageRetrievalListener listener) throws MessagingException {
146         throw new MessagingException("Not implemented");
147     }
148 
appendMessage(Context context, Message message, final boolean noTimeout)149     public abstract void appendMessage(Context context, Message message, final boolean noTimeout)
150             throws MessagingException;
151 
152     /**
153      * Copies the given messages to the destination folder.
154      */
copyMessages(Message[] msgs, Folder folder, MessageUpdateCallbacks callbacks)155     public abstract void copyMessages(Message[] msgs, Folder folder,
156             MessageUpdateCallbacks callbacks) throws MessagingException;
157 
setFlags(Message[] messages, Flag[] flags, boolean value)158     public abstract void setFlags(Message[] messages, Flag[] flags, boolean value)
159             throws MessagingException;
160 
expunge()161     public abstract Message[] expunge() throws MessagingException;
162 
fetch(Message[] messages, FetchProfile fp, MessageRetrievalListener listener)163     public abstract void fetch(Message[] messages, FetchProfile fp,
164             MessageRetrievalListener listener) throws MessagingException;
165 
delete(boolean recurse)166     public abstract void delete(boolean recurse) throws MessagingException;
167 
getName()168     public abstract String getName();
169 
getPermanentFlags()170     public abstract Flag[] getPermanentFlags() throws MessagingException;
171 
172     /**
173      * This method returns a string identifying the name of a "role" folder
174      * (such as inbox, draft, sent, or trash).  Stores that do not implement this
175      * feature can be used - the account UI will provide default strings.  To
176      * let the server identify specific folder roles, simply override this method.
177      *
178      * @return The server- or protocol- specific role for this folder.  If some roles are known
179      * but this is not one of them, return FolderRole.OTHER.  If roles are unsupported here,
180      * return FolderRole.UNKNOWN.
181      */
getRole()182     public FolderRole getRole() {
183         return FolderRole.UNKNOWN;
184     }
185 
186     /**
187      * Create an empty message of the appropriate type for the Folder.
188      */
createMessage(String uid)189     public abstract Message createMessage(String uid) throws MessagingException;
190 
191     /**
192      * Callback interface by which a folder can report UID changes caused by certain operations.
193      */
194     public interface MessageUpdateCallbacks {
195         /**
196          * The operation caused the message's UID to change
197          * @param message The message for which the UID changed
198          * @param newUid The new UID for the message
199          */
onMessageUidChange(Message message, String newUid)200         public void onMessageUidChange(Message message, String newUid) throws MessagingException;
201 
202         /**
203          * The operation could not be completed because the message doesn't exist
204          * (for example, it was already deleted from the server side.)
205          * @param message The message that does not exist
206          * @throws MessagingException
207          */
onMessageNotFound(Message message)208         public void onMessageNotFound(Message message) throws MessagingException;
209     }
210 
211     @Override
toString()212     public String toString() {
213         return getName();
214     }
215 }
216