0
# Store and Folder Management
1
2
Store and folder management provides comprehensive capabilities for accessing mail stores, managing folders, and organizing messages within mailboxes.
3
4
## Store Operations
5
6
The Store abstract class provides access to message repositories such as IMAP servers, POP3 servers, or local mailboxes.
7
8
```java { .api }
9
public abstract class Store extends Service {
10
// Folder access
11
public abstract Folder getDefaultFolder() throws MessagingException;
12
public abstract Folder getFolder(String name) throws MessagingException;
13
public abstract Folder getFolder(URLName url) throws MessagingException;
14
15
// Event handling
16
public void addStoreListener(StoreListener l);
17
public void removeStoreListener(StoreListener l);
18
19
// Store information
20
public Folder[] getPersonalNamespaces() throws MessagingException;
21
public Folder[] getUserNamespaces(String user) throws MessagingException;
22
public Folder[] getSharedNamespaces() throws MessagingException;
23
}
24
```
25
26
### Store Usage Example
27
28
```java
29
import jakarta.mail.*;
30
import java.util.Properties;
31
32
// Configure properties for IMAP store
33
Properties props = new Properties();
34
props.put("mail.store.protocol", "imaps");
35
props.put("mail.imaps.host", "imap.gmail.com");
36
props.put("mail.imaps.port", "993");
37
props.put("mail.imaps.ssl.enable", "true");
38
39
Session session = Session.getInstance(props);
40
41
// Connect to store
42
Store store = session.getStore("imaps");
43
store.connect("imap.gmail.com", "username@gmail.com", "password");
44
45
try {
46
// Get default folder (usually root)
47
Folder defaultFolder = store.getDefaultFolder();
48
System.out.println("Default folder: " + defaultFolder.getFullName());
49
50
// Get inbox
51
Folder inbox = store.getFolder("INBOX");
52
53
// List all folders
54
Folder[] folders = defaultFolder.list("*");
55
for (Folder folder : folders) {
56
System.out.println("Folder: " + folder.getFullName());
57
}
58
} finally {
59
store.close();
60
}
61
```
62
63
## Folder Operations
64
65
The Folder abstract class represents a container for messages and provides comprehensive folder management capabilities.
66
67
```java { .api }
68
public abstract class Folder implements AutoCloseable {
69
// Folder constants
70
public static final int HOLDS_MESSAGES = 0x01;
71
public static final int HOLDS_FOLDERS = 0x02;
72
public static final int READ_ONLY = 1;
73
public static final int READ_WRITE = 2;
74
75
// Basic folder properties
76
public abstract String getName();
77
public abstract String getFullName();
78
public abstract Folder getParent() throws MessagingException;
79
public abstract int getType() throws MessagingException;
80
public abstract boolean exists() throws MessagingException;
81
82
// Folder operations
83
public abstract boolean create(int type) throws MessagingException;
84
public abstract boolean delete(boolean recurse) throws MessagingException;
85
public abstract boolean renameTo(Folder f) throws MessagingException;
86
87
// Folder access
88
public abstract void open(int mode) throws MessagingException;
89
public abstract void close(boolean expunge) throws MessagingException;
90
public abstract boolean isOpen();
91
public int getMode();
92
93
// Message access
94
public abstract int getMessageCount() throws MessagingException;
95
public abstract Message getMessage(int msgnum) throws MessagingException;
96
public abstract Message[] getMessages() throws MessagingException;
97
public abstract Message[] getMessages(int start, int end) throws MessagingException;
98
public abstract Message[] getMessages(int[] msgnums) throws MessagingException;
99
100
// New/unread message counts
101
public int getNewMessageCount() throws MessagingException;
102
public int getUnreadMessageCount() throws MessagingException;
103
public int getDeletedMessageCount() throws MessagingException;
104
105
// Message operations
106
public abstract void appendMessages(Message[] msgs) throws MessagingException;
107
public abstract Message[] expunge() throws MessagingException;
108
public abstract Message[] search(SearchTerm term) throws MessagingException;
109
public abstract Message[] search(SearchTerm term, Message[] msgs) throws MessagingException;
110
111
// Folder hierarchy
112
public abstract Folder[] list() throws MessagingException;
113
public abstract Folder[] list(String pattern) throws MessagingException;
114
public abstract Folder[] listSubscribed() throws MessagingException;
115
public abstract Folder[] listSubscribed(String pattern) throws MessagingException;
116
117
// Subscription management
118
public abstract boolean isSubscribed() throws MessagingException;
119
public abstract void setSubscribed(boolean subscribe) throws MessagingException;
120
121
// Event handling
122
public void addConnectionListener(ConnectionListener l);
123
public void removeConnectionListener(ConnectionListener l);
124
public void addFolderListener(FolderListener l);
125
public void removeFolderListener(FolderListener l);
126
public void addMessageChangedListener(MessageChangedListener l);
127
public void removeMessageChangedListener(MessageChangedListener l);
128
public void addMessageCountListener(MessageCountListener l);
129
public void removeMessageCountListener(MessageCountListener l);
130
131
// Store reference
132
public Store getStore();
133
134
// String representation
135
public String toString();
136
}
137
```
138
139
### Folder Usage Example
140
141
```java
142
import jakarta.mail.*;
143
import jakarta.mail.search.*;
144
145
// Open inbox for reading
146
Folder inbox = store.getFolder("INBOX");
147
inbox.open(Folder.READ_ONLY);
148
149
try {
150
// Get folder information
151
System.out.println("Folder name: " + inbox.getName());
152
System.out.println("Full name: " + inbox.getFullName());
153
System.out.println("Message count: " + inbox.getMessageCount());
154
System.out.println("New messages: " + inbox.getNewMessageCount());
155
System.out.println("Unread messages: " + inbox.getUnreadMessageCount());
156
157
// Check folder capabilities
158
if ((inbox.getType() & Folder.HOLDS_MESSAGES) != 0) {
159
System.out.println("Folder can hold messages");
160
}
161
if ((inbox.getType() & Folder.HOLDS_FOLDERS) != 0) {
162
System.out.println("Folder can hold subfolders");
163
}
164
165
// Get all messages
166
Message[] messages = inbox.getMessages();
167
168
// Get recent messages only
169
Message[] recentMessages = inbox.search(new FlagTerm(new Flags(Flags.Flag.RECENT), true));
170
171
// Get messages from specific range
172
if (messages.length > 10) {
173
Message[] lastTen = inbox.getMessages(messages.length - 9, messages.length);
174
}
175
176
} finally {
177
inbox.close(false); // Don't expunge on close
178
}
179
```
180
181
## Folder Management Operations
182
183
### Creating and Managing Folders
184
185
```java
186
// Create new folder
187
Folder newFolder = store.getFolder("Archive");
188
if (!newFolder.exists()) {
189
boolean created = newFolder.create(Folder.HOLDS_MESSAGES);
190
if (created) {
191
System.out.println("Folder created successfully");
192
}
193
}
194
195
// Create folder hierarchy
196
Folder projectFolder = store.getFolder("Projects");
197
if (!projectFolder.exists()) {
198
projectFolder.create(Folder.HOLDS_FOLDERS);
199
}
200
201
Folder subFolder = store.getFolder("Projects/Project1");
202
if (!subFolder.exists()) {
203
subFolder.create(Folder.HOLDS_MESSAGES);
204
}
205
206
// Rename folder
207
Folder oldFolder = store.getFolder("OldName");
208
Folder newFolderName = store.getFolder("NewName");
209
if (oldFolder.exists()) {
210
boolean renamed = oldFolder.renameTo(newFolderName);
211
if (renamed) {
212
System.out.println("Folder renamed successfully");
213
}
214
}
215
216
// Delete folder
217
Folder folderToDelete = store.getFolder("Temporary");
218
if (folderToDelete.exists()) {
219
// Close if open
220
if (folderToDelete.isOpen()) {
221
folderToDelete.close(false);
222
}
223
224
boolean deleted = folderToDelete.delete(false); // Don't delete recursively
225
if (deleted) {
226
System.out.println("Folder deleted successfully");
227
}
228
}
229
```
230
231
### Folder Hierarchy Navigation
232
233
```java
234
// List all folders
235
Folder rootFolder = store.getDefaultFolder();
236
Folder[] allFolders = rootFolder.list("*");
237
238
for (Folder folder : allFolders) {
239
System.out.println("Folder: " + folder.getFullName());
240
241
// Get parent
242
Folder parent = folder.getParent();
243
if (parent != null) {
244
System.out.println(" Parent: " + parent.getFullName());
245
}
246
247
// Check if it has subfolders
248
if ((folder.getType() & Folder.HOLDS_FOLDERS) != 0) {
249
Folder[] subfolders = folder.list();
250
for (Folder subfolder : subfolders) {
251
System.out.println(" Subfolder: " + subfolder.getName());
252
}
253
}
254
}
255
256
// List only subscribed folders
257
Folder[] subscribedFolders = rootFolder.listSubscribed("*");
258
for (Folder folder : subscribedFolders) {
259
System.out.println("Subscribed: " + folder.getFullName());
260
}
261
262
// Pattern matching for folder listing
263
Folder[] inboxFolders = rootFolder.list("INBOX*");
264
Folder[] sentFolders = rootFolder.list("Sent*");
265
```
266
267
## Message Operations within Folders
268
269
### Moving and Copying Messages
270
271
```java
272
// Open source and destination folders
273
Folder inbox = store.getFolder("INBOX");
274
Folder archive = store.getFolder("Archive");
275
276
inbox.open(Folder.READ_WRITE);
277
if (!archive.exists()) {
278
archive.create(Folder.HOLDS_MESSAGES);
279
}
280
281
try {
282
// Get messages to move
283
Message[] messages = inbox.getMessages();
284
Message[] oldMessages = Arrays.stream(messages)
285
.filter(msg -> {
286
try {
287
Date sentDate = msg.getSentDate();
288
if (sentDate != null) {
289
long daysDiff = (System.currentTimeMillis() - sentDate.getTime()) / (1000 * 60 * 60 * 24);
290
return daysDiff > 30; // Older than 30 days
291
}
292
return false;
293
} catch (MessagingException e) {
294
return false;
295
}
296
})
297
.toArray(Message[]::new);
298
299
if (oldMessages.length > 0) {
300
// Copy messages to archive
301
archive.appendMessages(oldMessages);
302
303
// Mark original messages as deleted
304
for (Message msg : oldMessages) {
305
msg.setFlag(Flags.Flag.DELETED, true);
306
}
307
308
// Expunge to actually remove deleted messages
309
inbox.expunge();
310
311
System.out.println("Moved " + oldMessages.length + " messages to archive");
312
}
313
314
} finally {
315
inbox.close(false);
316
}
317
```
318
319
### Message Fetching Optimization
320
321
```java
322
// Use FetchProfile for efficient bulk operations
323
FetchProfile fetchProfile = new FetchProfile();
324
fetchProfile.add(FetchProfile.Item.ENVELOPE);
325
fetchProfile.add(FetchProfile.Item.FLAGS);
326
fetchProfile.add("X-mailer");
327
328
// Fetch specified attributes for all messages
329
Message[] messages = inbox.getMessages();
330
inbox.fetch(messages, fetchProfile);
331
332
// Now access is more efficient
333
for (Message message : messages) {
334
System.out.println("From: " + Arrays.toString(message.getFrom()));
335
System.out.println("Subject: " + message.getSubject());
336
System.out.println("Flags: " + message.getFlags());
337
}
338
```
339
340
## UID-Based Operations
341
342
For stores that support UIDs (like IMAP), you can use UID-based operations for more reliable message tracking.
343
344
```java { .api }
345
// UID folder interface
346
public interface UIDFolder {
347
public static final class FetchProfileItem extends FetchProfile.Item {
348
public static final FetchProfileItem UID;
349
}
350
351
public long getUID(Message message) throws MessagingException;
352
public Message getMessageByUID(long uid) throws MessagingException;
353
public Message[] getMessagesByUID(long start, long end) throws MessagingException;
354
public Message[] getMessagesByUID(long[] uids) throws MessagingException;
355
public long getUIDValidity() throws MessagingException;
356
public long getUIDNext() throws MessagingException;
357
}
358
```
359
360
### UID Usage Example
361
362
```java
363
if (inbox instanceof UIDFolder) {
364
UIDFolder uidFolder = (UIDFolder) inbox;
365
366
// Get message by UID (more reliable than message number)
367
Message message = uidFolder.getMessageByUID(12345L);
368
369
// Get UID for a message
370
long uid = uidFolder.getUID(message);
371
System.out.println("Message UID: " + uid);
372
373
// Get messages by UID range
374
Message[] messages = uidFolder.getMessagesByUID(1000L, 2000L);
375
376
// Get folder UID validity (changes when folder is rebuilt)
377
long uidValidity = uidFolder.getUIDValidity();
378
System.out.println("UID Validity: " + uidValidity);
379
}
380
```
381
382
## Quota Management
383
384
For stores that support quotas, you can monitor and manage storage limits.
385
386
```java { .api }
387
// Quota-aware store interface
388
public interface QuotaAwareStore {
389
public Quota[] getQuota(String quotaRoot) throws MessagingException;
390
public void setQuota(Quota quota) throws MessagingException;
391
}
392
393
// Quota information
394
public class Quota {
395
public static final class Resource {
396
public static final Resource STORAGE;
397
public static final Resource MESSAGE;
398
399
public String name;
400
public long usage;
401
public long limit;
402
}
403
404
public String quotaRoot;
405
public Resource[] resources;
406
}
407
```
408
409
### Quota Usage Example
410
411
```java
412
if (store instanceof QuotaAwareStore) {
413
QuotaAwareStore quotaStore = (QuotaAwareStore) store;
414
415
// Get quota information
416
Quota[] quotas = quotaStore.getQuota("INBOX");
417
for (Quota quota : quotas) {
418
System.out.println("Quota root: " + quota.quotaRoot);
419
for (Quota.Resource resource : quota.resources) {
420
System.out.println("Resource: " + resource.name);
421
System.out.println("Usage: " + resource.usage);
422
System.out.println("Limit: " + resource.limit);
423
if (resource.limit > 0) {
424
double percentage = (double) resource.usage / resource.limit * 100;
425
System.out.println("Usage: " + String.format("%.1f%%", percentage));
426
}
427
}
428
}
429
}
430
```