1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5 *
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common Development
8 * and Distribution License("CDDL") (collectively, the "License"). You
9 * may not use this file except in compliance with the License. You can obtain
10 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
11 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
12 * language governing permissions and limitations under the License.
13 *
14 * When distributing the software, include this License Header Notice in each
15 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
16 * Sun designates this particular file as subject to the "Classpath" exception
17 * as provided by Sun in the GPL Version 2 section of the License file that
18 * accompanied this code. If applicable, add the following below the License
19 * Header, with the fields enclosed by brackets [] replaced by your own
20 * identifying information: "Portions Copyrighted [year]
21 * [name of copyright owner]"
22 *
23 * Contributor(s):
24 *
25 * If you wish your version of this file to be governed by only the CDDL or
26 * only the GPL Version 2, indicate your decision by adding "[Contributor]
27 * elects to include this software in this distribution under the [CDDL or GPL
28 * Version 2] license." If you don't indicate a single choice of license, a
29 * recipient has the option to distribute your version of this file under
30 * either the CDDL, the GPL Version 2 or to extend the choice of license to
31 * its licensees as provided above. However, if you add GPL Version 2 code
32 * and therefore, elected the GPL Version 2 license, then the option applies
33 * only if the new code is made subject to such option by the copyright
34 * holder.
35 */
36
37 /*
38 * @(#)Store.java 1.28 07/05/04
39 */
40
41 package javax.mail;
42
43 import java.io;
44 import java.net;
45 import java.util;
46 import javax.mail.event;
47
48 /**
49 * An abstract class that models a message store and its
50 * access protocol, for storing and retrieving messages.
51 * Subclasses provide actual implementations. <p>
52 *
53 * Note that <code>Store</code> extends the <code>Service</code>
54 * class, which provides many common methods for naming stores,
55 * connecting to stores, and listening to connection events.
56 *
57 * @author John Mani
58 * @author Bill Shannon
59 * @version 1.28, 07/05/04
60 *
61 * @see javax.mail.Service
62 * @see javax.mail.event.ConnectionEvent
63 * @see javax.mail.event.StoreEvent
64 */
65
66 public abstract class Store extends Service {
67
68 /**
69 * Constructor.
70 *
71 * @param session Session object for this Store.
72 * @param urlname URLName object to be used for this Store
73 */
74 protected Store(Session session, URLName urlname) {
75 super(session, urlname);
76 }
77
78 /**
79 * Returns a Folder object that represents the 'root' of
80 * the default namespace presented to the user by the Store.
81 *
82 * @return the root Folder
83 * @exception IllegalStateException if this Store is not connected.
84 */
85 public abstract Folder getDefaultFolder() throws MessagingException;
86
87 /**
88 * Return the Folder object corresponding to the given name. Note
89 * that a Folder object is returned even if the named folder does
90 * not physically exist on the Store. The <code>exists()</code>
91 * method on the folder object indicates whether this folder really
92 * exists. <p>
93 *
94 * Folder objects are not cached by the Store, so invoking this
95 * method on the same name multiple times will return that many
96 * distinct Folder objects.
97 *
98 * @param name The name of the Folder. In some Stores, name can
99 * be an absolute path if it starts with the
100 * hierarchy delimiter. Else it is interpreted
101 * relative to the 'root' of this namespace.
102 * @return Folder object
103 * @exception IllegalStateException if this Store is not connected.
104 * @see Folder#exists
105 * @see Folder#create
106 */
107 public abstract Folder getFolder(String name)
108 throws MessagingException;
109
110 /**
111 * Return a closed Folder object, corresponding to the given
112 * URLName. The store specified in the given URLName should
113 * refer to this Store object. <p>
114 *
115 * Implementations of this method may obtain the name of the
116 * actual folder using the <code>getFile()</code> method on
117 * URLName, and use that name to create the folder.
118 *
119 * @param url URLName that denotes a folder
120 * @see URLName
121 * @exception IllegalStateException if this Store is not connected.
122 * @return Folder object
123 */
124 public abstract Folder getFolder(URLName url)
125 throws MessagingException;
126
127 /**
128 * Return a set of folders representing the <i>personal</i> namespaces
129 * for the current user. A personal namespace is a set of names that
130 * is considered within the personal scope of the authenticated user.
131 * Typically, only the authenticated user has access to mail folders
132 * in their personal namespace. If an INBOX exists for a user, it
133 * must appear within the user's personal namespace. In the
134 * typical case, there should be only one personal namespace for each
135 * user in each Store. <p>
136 *
137 * This implementation returns an array with a single entry containing
138 * the return value of the <code>getDefaultFolder</code> method.
139 * Subclasses should override this method to return appropriate information.
140 *
141 * @exception IllegalStateException if this Store is not connected.
142 * @return array of Folder objects
143 * @since JavaMail 1.2
144 */
145 public Folder[] getPersonalNamespaces() throws MessagingException {
146 return new Folder[] { getDefaultFolder() };
147 }
148
149 /**
150 * Return a set of folders representing the namespaces for
151 * <code>user</code>. The namespaces returned represent the
152 * personal namespaces for the user. To access mail folders in the
153 * other user's namespace, the currently authenticated user must be
154 * explicitly granted access rights. For example, it is common for
155 * a manager to grant to their secretary access rights to their
156 * mail folders. <p>
157 *
158 * This implementation returns an empty array. Subclasses should
159 * override this method to return appropriate information.
160 *
161 * @exception IllegalStateException if this Store is not connected.
162 * @return array of Folder objects
163 * @since JavaMail 1.2
164 */
165 public Folder[] getUserNamespaces(String user)
166 throws MessagingException {
167 return new Folder[0];
168 }
169
170 /**
171 * Return a set of folders representing the <i>shared</i> namespaces.
172 * A shared namespace is a namespace that consists of mail folders
173 * that are intended to be shared amongst users and do not exist
174 * within a user's personal namespace. <p>
175 *
176 * This implementation returns an empty array. Subclasses should
177 * override this method to return appropriate information.
178 *
179 * @exception IllegalStateException if this Store is not connected.
180 * @return array of Folder objects
181 * @since JavaMail 1.2
182 */
183 public Folder[] getSharedNamespaces() throws MessagingException {
184 return new Folder[0];
185 }
186
187 // Vector of Store listeners
188 private volatile Vector storeListeners = null;
189
190 /**
191 * Add a listener for StoreEvents on this Store. <p>
192 *
193 * The default implementation provided here adds this listener
194 * to an internal list of StoreListeners.
195 *
196 * @param l the Listener for Store events
197 * @see javax.mail.event.StoreEvent
198 */
199 public synchronized void addStoreListener(StoreListener l) {
200 if (storeListeners == null)
201 storeListeners = new Vector();
202 storeListeners.addElement(l);
203 }
204
205 /**
206 * Remove a listener for Store events. <p>
207 *
208 * The default implementation provided here removes this listener
209 * from the internal list of StoreListeners.
210 *
211 * @param l the listener
212 * @see #addStoreListener
213 */
214 public synchronized void removeStoreListener(StoreListener l) {
215 if (storeListeners != null)
216 storeListeners.removeElement(l);
217 }
218
219 /**
220 * Notify all StoreListeners. Store implementations are
221 * expected to use this method to broadcast StoreEvents. <p>
222 *
223 * The provided default implementation queues the event into
224 * an internal event queue. An event dispatcher thread dequeues
225 * events from the queue and dispatches them to the registered
226 * StoreListeners. Note that the event dispatching occurs
227 * in a separate thread, thus avoiding potential deadlock problems.
228 */
229 protected void notifyStoreListeners(int type, String message) {
230 if (storeListeners == null)
231 return;
232
233 StoreEvent e = new StoreEvent(this, type, message);
234 queueEvent(e, storeListeners);
235 }
236
237 // Vector of folder listeners
238 private volatile Vector folderListeners = null;
239
240 /**
241 * Add a listener for Folder events on any Folder object
242 * obtained from this Store. FolderEvents are delivered to
243 * FolderListeners on the affected Folder as well as to
244 * FolderListeners on the containing Store. <p>
245 *
246 * The default implementation provided here adds this listener
247 * to an internal list of FolderListeners.
248 *
249 * @param l the Listener for Folder events
250 * @see javax.mail.event.FolderEvent
251 */
252 public synchronized void addFolderListener(FolderListener l) {
253 if (folderListeners == null)
254 folderListeners = new Vector();
255 folderListeners.addElement(l);
256 }
257
258 /**
259 * Remove a listener for Folder events. <p>
260 *
261 * The default implementation provided here removes this listener
262 * from the internal list of FolderListeners.
263 *
264 * @param l the listener
265 * @see #addFolderListener
266 */
267 public synchronized void removeFolderListener(FolderListener l) {
268 if (folderListeners != null)
269 folderListeners.removeElement(l);
270 }
271
272 /**
273 * Notify all FolderListeners. Store implementations are
274 * expected to use this method to broadcast Folder events. <p>
275 *
276 * The provided default implementation queues the event into
277 * an internal event queue. An event dispatcher thread dequeues
278 * events from the queue and dispatches them to the registered
279 * FolderListeners. Note that the event dispatching occurs
280 * in a separate thread, thus avoiding potential deadlock problems.
281 *
282 * @param type type of FolderEvent
283 * @param folder affected Folder
284 * @see #notifyFolderRenamedListeners
285 */
286 protected void notifyFolderListeners(int type, Folder folder) {
287 if (folderListeners == null)
288 return;
289
290 FolderEvent e = new FolderEvent(this, folder, type);
291 queueEvent(e, folderListeners);
292 }
293
294 /**
295 * Notify all FolderListeners about the renaming of a folder.
296 * Store implementations are expected to use this method to broadcast
297 * Folder events indicating the renaming of folders. <p>
298 *
299 * The provided default implementation queues the event into
300 * an internal event queue. An event dispatcher thread dequeues
301 * events from the queue and dispatches them to the registered
302 * FolderListeners. Note that the event dispatching occurs
303 * in a separate thread, thus avoiding potential deadlock problems.
304 *
305 * @param oldF the folder being renamed
306 * @param newF the folder representing the new name.
307 * @since JavaMail 1.1
308 */
309 protected void notifyFolderRenamedListeners(Folder oldF, Folder newF) {
310 if (folderListeners == null)
311 return;
312
313 FolderEvent e = new FolderEvent(this, oldF, newF,FolderEvent.RENAMED);
314 queueEvent(e, folderListeners);
315 }
316 }