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