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 { messageRetrieved(Message message)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 */ open(OpenMode mode, PersistentDataCallbacks callbacks)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 */ close(boolean expunge)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 isOpen()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 */ getMode()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 */ canCreate(FolderType type)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 */ create(FolderType type)100 public abstract boolean create(FolderType type) throws MessagingException; 101 exists()102 public abstract boolean exists() throws MessagingException; 103 104 /** 105 * @return A count of the messages in the selected folder. 106 */ getMessageCount()107 public abstract int getMessageCount() throws MessagingException; 108 getUnreadMessageCount()109 public abstract int getUnreadMessageCount() throws MessagingException; 110 getMessage(String uid)111 public abstract Message getMessage(String uid) throws MessagingException; 112 getMessages(int start, int end, MessageRetrievalListener listener)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 */ getMessages(MessageRetrievalListener listener)125 public abstract Message[] getMessages(MessageRetrievalListener listener) 126 throws MessagingException; 127 getMessages(String[] uids, MessageRetrievalListener listener)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 */ getMessages(Flag[] setFlags, Flag[] clearFlags, MessageRetrievalListener listener)141 public Message[] getMessages(Flag[] setFlags, Flag[] clearFlags, 142 MessageRetrievalListener listener) throws MessagingException { 143 throw new MessagingException("Not implemented"); 144 } 145 appendMessages(Message[] messages)146 public abstract void appendMessages(Message[] messages) throws MessagingException; 147 copyMessages(Message[] msgs, Folder folder, MessageUpdateCallbacks callbacks)148 public abstract void copyMessages(Message[] msgs, Folder folder, 149 MessageUpdateCallbacks callbacks) throws MessagingException; 150 setFlags(Message[] messages, Flag[] flags, boolean value)151 public abstract void setFlags(Message[] messages, Flag[] flags, boolean value) 152 throws MessagingException; 153 expunge()154 public abstract Message[] expunge() throws MessagingException; 155 fetch(Message[] messages, FetchProfile fp, MessageRetrievalListener listener)156 public abstract void fetch(Message[] messages, FetchProfile fp, 157 MessageRetrievalListener listener) throws MessagingException; 158 delete(boolean recurse)159 public abstract void delete(boolean recurse) throws MessagingException; 160 getName()161 public abstract String getName(); 162 getPermanentFlags()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 */ getRole()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") localFolderSetupComplete(Folder localFolder)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 */ createMessage(String uid)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 */ setPersistentString(String key, String value)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 */ getPersistentString(String key, String defaultValue)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 */ setPersistentStringAndMessageFlags(String key, String value, Flag[] setFlags, Flag[] clearFlags)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 */ onMessageUidChange(Message message, String newUid)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 */ onMessageNotFound(Message message)249 public void onMessageNotFound(Message message) throws MessagingException; 250 } 251 252 @Override toString()253 public String toString() { 254 return getName(); 255 } 256 } 257