1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2/* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6#include "nsISupports.idl" 7 8interface nsIMsgFolder; 9interface nsIMsgCopyServiceListener; 10interface nsIMsgDBHdr; 11interface nsIMsgWindow; 12interface nsIOutputStream; 13interface nsIInputStream; 14interface nsIUrlListener; 15interface nsIMsgDatabase; 16interface nsITransaction; 17 18[scriptable, uuid(F732CE58-E540-4dc4-B803-9456056EBEFC)] 19 20/** 21 * Pluggable message store interface. Each incoming server can have a different 22 * message store. 23 * All methods are synchronous unless otherwise specified. 24 */ 25interface nsIMsgPluggableStore : nsISupports { 26 /** 27 * Examines the store and adds subfolders for the existing folders in the 28 * profile directory. aParentFolder->AddSubfolder is the normal way 29 * to register the subfolders. This method is expected to be synchronous. 30 * This shouldn't be confused with server folder discovery, which is allowed 31 * to be asynchronous. 32 * 33 * @param aParentFolder folder whose existing children we want to discover. 34 * This will be the root folder for the server object. 35 * @param aDeep true if we should discover all descendents. Would we ever 36 * not want to do this? 37 */ 38 39 void discoverSubFolders(in nsIMsgFolder aParentFolder, in boolean aDeep); 40 /** 41 * Creates storage for a new, empty folder. 42 * 43 * @param aParent parent folder 44 * @param aFolderName leaf name of folder. 45 * @return newly created folder. 46 * @exception NS_MSG_FOLDER_EXISTS If the child exists. 47 * @exception NS_MSG_CANT_CREATE_FOLDER for other errors. 48 */ 49 nsIMsgFolder createFolder(in nsIMsgFolder aParent, in AString aFolderName); 50 51 /** 52 * Delete storage for a folder and its subfolders, if any. 53 * This is a real delete, not a move to the trash folder. 54 * 55 * @param aFolder folder to delete 56 */ 57 void deleteFolder(in nsIMsgFolder aFolder); 58 59 /** 60 * Rename storage for an existing folder. 61 * 62 * @param aFolder folder to rename 63 * @param aNewName name to give new folder 64 * @return the renamed folder object 65 */ 66 nsIMsgFolder renameFolder(in nsIMsgFolder aFolder, in AString aNewName); 67 68 /** 69 * Tells if the store has the requested amount of space available in the 70 * specified folder. 71 * 72 * @param aFolder folder we want to add messages to. 73 * @param aSpaceRequested How many bytes we're trying to add to the store. 74 * 75 * The function returns an exception if there is not enough space to 76 * indicate the reason of the shortage: 77 * NS_ERROR_FILE_TOO_BIG = the store cannot grow further due to internal limits 78 * NS_ERROR_FILE_NO_DEVICE_SPACE = there is not enough space on the disk 79 */ 80 boolean hasSpaceAvailable(in nsIMsgFolder aFolder, 81 in long long aSpaceRequested); 82 83 /** 84 * Move/Copy a folder to a new parent folder. This method is asynchronous. 85 * The store needs to use the aListener to notify the core code of the 86 * completion of the operation. And it must send the appropriate 87 * nsIMsgFolderNotificationService notifications. 88 * 89 * @param aSrcFolder folder to move/copy 90 * @param aDstFolder parent dest folder 91 * @param aIsMoveFolder true if move, false if copy. If move, source folder 92 * is deleted when copy completes. 93 * @param aMsgWindow used to display progress, may be null 94 * @param aListener - used to get notification when copy is done. 95 * @param aNewName Optional new name for the target folder. 96 * If rename is not needed, set this to empty string. 97 */ 98 void copyFolder(in nsIMsgFolder aSrcFolder, in nsIMsgFolder aDstFolder, 99 in boolean aIsMoveFolder, in nsIMsgWindow aMsgWindow, 100 in nsIMsgCopyServiceListener aListener, 101 in AString aNewName); 102 103 /** 104 * Get an output stream for a message in a folder. 105 * 106 * @param aFolder folder to create a message output stream for. 107 * @param aNewHdr If aNewHdr is set on input, then this is probably for 108 * offline storage of an existing message. If null, the 109 * this is a newly downloaded message and the store needs 110 * to create a new header for the new message. If the db 111 * is invalid, this can be null. But if the db is valid, 112 * the store should create a message header with the right 113 * message key, or whatever other property it needs to set to 114 * be able to retrieve the message contents later. If the store 115 * needs to base any of this on the contents of the message, 116 * it will need remember the message header and hook into 117 * the output stream somehow to alter the message header. 118 * @param aReusable set to true on output if the caller can reuse the 119 * stream for multiple messages, e.g., mbox format. 120 * This means the caller will likely get the same stream 121 * back on multiple calls to this method, and shouldn't 122 * close the stream in between calls if they want reuse. 123 * 124 * @return The output stream to write to. The output stream will be positioned 125 * for writing (e.g., for berkeley mailbox, it will be at the end). 126 */ 127 nsIOutputStream getNewMsgOutputStream(in nsIMsgFolder aFolder, 128 inout nsIMsgDBHdr aNewHdr, 129 out boolean aReusable); 130 131 /** 132 * Called when the current message is discarded, e.g., it is moved 133 * to an other folder as a filter action, or is deleted because it's 134 * a duplicate. This gives the berkeley mailbox store a chance to simply 135 * truncate the Inbox w/o leaving a deleted message in the store. 136 * 137 * @param aOutputStream stream we were writing the message to be discarded to 138 * @param aNewHdr header of message to discard 139 */ 140 void discardNewMessage(in nsIOutputStream aOutputStream, 141 in nsIMsgDBHdr aNewHdr); 142 143 /** 144 * Must be called by code that calls getNewMsgOutputStream to finish 145 * the process of storing a new message, if the new msg has not been 146 * discarded. Could/should this be combined with discardNewMessage? 147 * 148 * @param aOutputStream stream we were writing the message to. 149 * @param aNewHdr header of message finished. 150 */ 151 void finishNewMessage(in nsIOutputStream aOutputStream, 152 in nsIMsgDBHdr aNewHdr); 153 154 /** 155 * Called by pop3 message filters when a newly downloaded message is being 156 * moved by an incoming filter. This is called before finishNewMessage, and 157 * it allows the store to optimize that case. 158 * 159 * @param aNewHdr msg hdr of message being moved. 160 * @param aDestFolder folder to move message to, in the same store. 161 * 162 * @return true if successful, false if the store doesn't want to optimize 163 * this. 164 * @exception If the moved failed. values TBD 165 */ 166 boolean moveNewlyDownloadedMessage(in nsIMsgDBHdr aNewHdr, 167 in nsIMsgFolder aDestFolder); 168 169 /** 170 * Get an input stream that we can read the contents of a message from. 171 * If the input stream is reusable, and the caller is going to ask 172 * for input streams for other messages in the folder, then the caller 173 * should not close the stream until it is done with its messages. 174 * 175 * @param aMsgFolder Folder containing the message 176 * @param aMsgToken token that identifies message. This is store-dependent, 177 * and must be set as a string property "storeToken" on the 178 * message hdr by the store when the message is added 179 * to the store. 180 * @param aOffset offset in the returned stream of the message. 181 * @param[optional] aHdr msgHdr to use in case storeToken is not set. This is 182 * for upgrade from existing profiles. 183 * @param[optional] aReusable Is the returned stream re-usable for other 184 * messages' input streams? 185 */ 186 nsIInputStream getMsgInputStream(in nsIMsgFolder aFolder, 187 in ACString aMsgToken, 188 out long long aOffset, 189 [optional] in nsIMsgDBHdr aHdr, 190 [optional] out boolean aReusable); 191 192 /** 193 * Delete the passed in messages. These message should all be in the 194 * same folder. 195 * @param aHdrArray array of nsIMsgDBHdr's. 196 */ 197 void deleteMessages(in Array<nsIMsgDBHdr> aHdrArray); 198 199 /** 200 * This allows the store to handle a msg move/copy if it wants. This lets 201 * it optimize move/copies within the same store. E.g., for maildir, a 202 * msg move mostly entails moving the file containing the message, and 203 * updating the db. If the store does not want to implement this, the core 204 * code will use getMsgInputStream on the source message, 205 * getNewMsgOutputStream for the dest message, and stream the input to 206 * the output. This operation can be asynchronous. 207 * If the store does the copy, it must return the appropriate undo action, 208 * which can be store dependent. And it must send the appropriate 209 * nsIMsgFolderNotificationService notifications. 210 * 211 * @param isMove true if this is a move, false if it is a copy. 212 * @param aHdrArray array of nsIMsgDBHdr's, all in the same folder 213 * @param aDstFolder folder to move/copy the messages to. 214 * @param aListener listener to notify of copy status. 215 * @param aDstHdrs array of nsIMsgDBHdr's in the destination folder. 216 * @param[out,optional] aUndoAction transaction to provide undo, if 217 * the store does the copy itself. 218 * @return true if messages were copied, false if the core code should 219 * do the copy. 220 */ 221 boolean copyMessages(in boolean isMove, 222 in Array<nsIMsgDBHdr> aHdrArray, 223 in nsIMsgFolder aDstFolder, 224 in nsIMsgCopyServiceListener aListener, 225 out Array<nsIMsgDBHdr> aDstHdrs, 226 out nsITransaction aUndoAction); 227 228 /** 229 * Does this store require compaction? For example, maildir doesn't require 230 * compaction at all. Berkeley mailbox does. A sqlite store probably doesn't. 231 * This is a static property of the store. It doesn't mean that any particular 232 * folder has space that can be reclaimed via compaction. Right now, the core 233 * code keeps track of the size of messages deleted, which it can use in 234 * conjunction with this store attribute. 235 */ 236 readonly attribute boolean supportsCompaction; 237 238 /** 239 * Remove deleted messages from the store, reclaiming space. Some stores 240 * won't need to do anything here (e.g., maildir), and those stores 241 * should return false for needsCompaction. This operation is asynchronous, 242 * and the passed url listener should be called when the operation is done. 243 * 244 * @param aFolder folder whose storage is to be compacted 245 * @param aListener listener notified when compaction is done. 246 * @param aMsgWindow window to display progress/status in. 247 */ 248 void compactFolder(in nsIMsgFolder aFolder, in nsIUrlListener aListener, 249 in nsIMsgWindow aMsgWindow); 250 251 /** 252 * Is the summary file for the passed folder valid? For Berkeley Mailboxes, 253 * for local mail folders, this checks the timestamp and size of the local 254 * mail folder against values stored in the db. For other stores, this may 255 * be a noop, though other stores could certainly become invalid. For 256 * Berkeley Mailboxes, this is to deal with the case of other apps altering 257 * mailboxes from outside mailnews code, and this is certainly possible 258 * with other stores. 259 * 260 * @param aFolder Folder to check if summary is valid for. 261 * @param aDB DB to check validity of. 262 * 263 * @return return true if the summary file is valid, false otherwise. 264 */ 265 boolean isSummaryFileValid(in nsIMsgFolder aFolder, in nsIMsgDatabase aDB); 266 267 /** 268 * Marks the summary file for aFolder as valid or invalid. This method 269 * may not be required, since it's really used by Berkeley Mailbox code 270 * to fix the timestamp and size for a folder. 271 * 272 * @param aFolder folder whose summary file should be marked (in)valid. 273 * @param aDB db to mark valid (may not be the folder's db in odd cases 274 * like folder compaction. 275 * @param aValid whether to mark it valid or invalid. 276 */ 277 void setSummaryFileValid(in nsIMsgFolder aFolder, in nsIMsgDatabase aDB, 278 in boolean aValid); 279 280 /** 281 * Rebuild the index from information in the store. This involves creating 282 * a new nsIMsgDatabase for the folder, adding the information for all the 283 * messages in the store, and then copying the new msg database over the 284 * existing database. For Berkeley mailbox, we try to maintain meta data 285 * stored in the existing database when possible, and other stores should do 286 * the same. Ideally, I would figure out a way of making that easy. That 287 * might entail reworking the rebuild index process into one where the store 288 * would iterate over the messages, and stream each message through the 289 * message parser, and the common code would handle maintaining the 290 * meta data. But the berkeley mailbox code needs to do some parsing because 291 * it doesn't know how big the message is (i.e., the stream can't simply be 292 * a file stream). 293 * This operation is asynchronous, 294 * and the passed url listener should be called when the operation is done. 295 * 296 * @param aFolder folder whose storage is to be compacted 297 * @param aMsgDB db to put parsed headers in. 298 * @param aMsgWindow msgWindow to use for progress updates. 299 * @param aListener listener notified when the index is rebuilt. 300 */ 301 void rebuildIndex(in nsIMsgFolder aFolder, in nsIMsgDatabase aMsgDB, 302 in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener); 303 304 /** 305 * Sets/Clears the passed flags on the passed messages. 306 * @param aHdrArray array of nsIMsgDBHdr's 307 * @param aFlags flags to set/clear 308 * @param aSet true to set the flag(s), false to clear. 309 */ 310 void changeFlags(in Array<nsIMsgDBHdr> aHdrArray, in unsigned long aFlags, 311 in boolean aSet); 312 /** 313 *Sets/Clears the passed keywords on the passed messages. 314 * @param aHdrArray array of nsIMsgDBHdr's 315 * @param aKeywords keywords to set/clear 316 * @param aAdd true to add the keyword(s), false to remove. 317 */ 318 void changeKeywords(in Array<nsIMsgDBHdr> aHdrArray, in ACString aKeywords, 319 in boolean aAdd); 320 321 /** 322 * Identifies a specific type of store. Please use this only for legacy 323 * bug fixes, and not as a method to change behavior! 324 * 325 * Typical values: "mbox", "maildir" 326 */ 327 readonly attribute ACString storeType; 328}; 329