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 * Forces an open of the MailProvider. If the provider is already open this 45 * function returns without doing anything. 46 * 47 * @param mode READ_ONLY or READ_WRITE 48 * @param callbacks Pointer to callbacks class. This may be used by the folder between this 49 * time and when close() is called. This is only used for remote stores - should be null 50 * for LocalStore.LocalFolder. 51 */ 52 public abstract void open(OpenMode mode, PersistentDataCallbacks callbacks) 53 throws MessagingException; 54 55 /** 56 * Forces a close of the MailProvider. Any further access will attempt to 57 * reopen the MailProvider. 58 * 59 * @param expunge If true all deleted messages will be expunged. 60 */ 61 public abstract void close(boolean expunge) throws MessagingException; 62 63 /** 64 * @return True if further commands are not expected to have to open the 65 * connection. 66 */ 67 // TODO not used, get rid of this - it's a transport function 68 public abstract boolean isOpen(); 69 70 /** 71 * Get the mode the folder was opened with. This may be different than the mode the open 72 * was requested with. 73 * @return 74 */ 75 public abstract OpenMode getMode() throws MessagingException; 76 77 /** 78 * Reports if the Store is able to create folders of the given type. 79 * Does not actually attempt to create a folder. 80 * @param type 81 * @return true if can create, false if cannot create 82 */ 83 public abstract boolean canCreate(FolderType type); 84 85 /** 86 * Attempt to create the given folder remotely using the given type. 87 * @param type 88 * @return true if created, false if cannot create (e.g. server side) 89 */ 90 public abstract boolean create(FolderType type) throws MessagingException; 91 92 public abstract boolean exists() throws MessagingException; 93 94 /** 95 * @return A count of the messages in the selected folder. 96 */ 97 public abstract int getMessageCount() throws MessagingException; 98 99 public abstract int getUnreadMessageCount() throws MessagingException; 100 101 public abstract Message getMessage(String uid) throws MessagingException; 102 103 public abstract Message[] getMessages(int start, int end, MessageRetrievalListener listener) 104 throws MessagingException; 105 106 /** 107 * Fetches the given list of messages. The specified listener is notified as 108 * each fetch completes. Messages are downloaded as (as) lightweight (as 109 * possible) objects to be filled in with later requests. In most cases this 110 * means that only the UID is downloaded. 111 * 112 * @param uids 113 * @param listener 114 */ 115 public abstract Message[] getMessages(MessageRetrievalListener listener) 116 throws MessagingException; 117 118 public abstract Message[] getMessages(String[] uids, MessageRetrievalListener listener) 119 throws MessagingException; 120 121 /** 122 * Return a set of messages based on the state of the flags. 123 * Note: Not typically implemented in remote stores, so not abstract. 124 * 125 * @param setFlags The flags that should be set for a message to be selected (can be null) 126 * @param clearFlags The flags that should be clear for a message to be selected (can be null) 127 * @param listener 128 * @return A list of messages matching the desired flag states. 129 * @throws MessagingException 130 */ 131 public Message[] getMessages(Flag[] setFlags, Flag[] clearFlags, 132 MessageRetrievalListener listener) throws MessagingException { 133 throw new MessagingException("Not implemented"); 134 } 135 136 public abstract void appendMessages(Message[] messages) throws MessagingException; 137 138 public abstract void copyMessages(Message[] msgs, Folder folder, 139 MessageUpdateCallbacks callbacks) throws MessagingException; 140 141 public abstract void setFlags(Message[] messages, Flag[] flags, boolean value) 142 throws MessagingException; 143 144 public abstract Message[] expunge() throws MessagingException; 145 146 public abstract void fetch(Message[] messages, FetchProfile fp, 147 MessageRetrievalListener listener) throws MessagingException; 148 149 public abstract void delete(boolean recurse) throws MessagingException; 150 151 public abstract String getName(); 152 153 public abstract Flag[] getPermanentFlags() throws MessagingException; 154 155 /** 156 * This method returns a string identifying the name of a "role" folder 157 * (such as inbox, draft, sent, or trash). Stores that do not implement this 158 * feature can be used - the account UI will provide default strings. To 159 * let the server identify specific folder roles, simply override this method. 160 * 161 * @return The server- or protocol- specific role for this folder. If some roles are known 162 * but this is not one of them, return FolderRole.OTHER. If roles are unsupported here, 163 * return FolderRole.UNKNOWN. 164 */ 165 public FolderRole getRole() { 166 return FolderRole.UNKNOWN; 167 } 168 169 /** 170 * This function will be called after the messaging controller has called 171 * getPersonalNamespaces() and has created a matching LocalFolder object. This can 172 * be used as a trigger for the folder to write back any folder-specific persistent data using 173 * callbacks. 174 * 175 * This is not abstract because most folders do not require this functionality and do not 176 * need to implement it. 177 */ 178 @SuppressWarnings("unused") 179 public void localFolderSetupComplete(Folder localFolder) throws MessagingException { 180 // Do nothing - return immediately 181 } 182 183 /** 184 * Create an empty message of the appropriate type for the Folder. 185 */ 186 public abstract Message createMessage(String uid) throws MessagingException; 187 188 /** 189 * Callback interface by which a Folder can read and write persistent data. 190 * TODO This needs to be made more generic & flexible 191 */ 192 public interface PersistentDataCallbacks { 193 194 /** 195 * Provides keyed storage of strings. Should be used for per-folder data. Do not use for 196 * per-message data. 197 * @param key identifier for the data (e.g. "sync.key" or "folder.id") 198 * @param value Data to persist. All data must be encoded into a string, 199 * so use base64 or some other encoding if necessary. 200 */ 201 public void setPersistentString(String key, String value); 202 203 /** 204 * @param key identifier for the data of interest 205 * @return the data saved by the Folder, or defaultValue if never set. 206 */ 207 public String getPersistentString(String key, String defaultValue); 208 209 /** 210 * In a single transaction: Set a key/value pair for the folder, and bulk set or clear 211 * message flags. Typically used at the beginning or conclusion of a bulk sync operation. 212 * 213 * @param key if non-null, the transaction will set this folder persistent value 214 * @param value the value that will be stored for the key 215 * @param setFlags if non-null, flag(s) will be set for all messages in the folder 216 * @param clearFlags if non-null, flag(s) will be cleared for all messages in the folder 217 */ 218 public void setPersistentStringAndMessageFlags(String key, String value, 219 Flag[] setFlags, Flag[] clearFlags) throws MessagingException; 220 } 221 222 /** 223 * Callback interface by which a folder can report UID changes caused by certain operations. 224 */ 225 public interface MessageUpdateCallbacks { 226 /** 227 * The operation caused the message's UID to change 228 * @param message The message for which the UID changed 229 * @param newUid The new UID for the message 230 */ 231 public void onMessageUidChange(Message message, String newUid) throws MessagingException; 232 233 /** 234 * The operation could not be completed because the message doesn't exist 235 * (for example, it was already deleted from the server side.) 236 * @param message The message that does not exist 237 * @throws MessagingException 238 */ 239 public void onMessageNotFound(Message message) throws MessagingException; 240 } 241 242 @Override 243 public String toString() { 244 return getName(); 245 } 246 } 247