1. /*
  2. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  3. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package javax.mail;
  6. import java.io.*;
  7. import java.net.*;
  8. import java.util.*;
  9. import javax.mail.event.*;
  10. /**
  11. * An abstract class that models a message store and its
  12. * access protocol, for storing and retrieving messages.
  13. * Subclasses provide actual implementations. <p>
  14. *
  15. * Note that <code>Store</code> extends the <code>Service</code>
  16. * class, which provides many common methods for naming stores,
  17. * connecting to stores, and listening to connection events.
  18. *
  19. * @author John Mani
  20. * @author Bill Shannon
  21. * @version 1.24, 00/08/29
  22. *
  23. * @see javax.mail.Service
  24. * @see javax.mail.event.ConnectionEvent
  25. * @see javax.mail.event.StoreEvent
  26. */
  27. public abstract class Store extends Service {
  28. /**
  29. * Constructor.
  30. *
  31. * @param session Session object for this Store.
  32. * @param url URLName object to be used for this Store
  33. */
  34. protected Store(Session session, URLName urlname) {
  35. super(session, urlname);
  36. }
  37. /**
  38. * Returns a Folder object that represents the 'root' of
  39. * the default namespace presented to the user by the Store.
  40. *
  41. * @return the root Folder
  42. * @exception IllegalStateException if this Store is not connected.
  43. */
  44. public abstract Folder getDefaultFolder() throws MessagingException;
  45. /**
  46. * Return the Folder object corresponding to the given name. Note
  47. * that a Folder object is returned even if the named folder does
  48. * not physically exist on the Store. The <code>exists()</code>
  49. * method on the folder object indicates whether this folder really
  50. * exists. <p>
  51. *
  52. * Folder objects are not cached by the Store, so invoking this
  53. * method on the same name multiple times will return that many
  54. * distinct Folder objects.
  55. *
  56. * @param name The name of the Folder. In some Stores, name can
  57. * be an absolute path if it starts with the
  58. * hierarchy delimiter. Else it is interpreted
  59. * relative to the 'root' of this namespace.
  60. * @return Folder object
  61. * @exception IllegalStateException if this Store is not connected.
  62. * @see Folder#exists
  63. * @see Folder#create
  64. */
  65. public abstract Folder getFolder(String name)
  66. throws MessagingException;
  67. /**
  68. * Return a closed Folder object, corresponding to the given
  69. * URLName. The store specified in the given URLName should
  70. * refer to this Store object. <p>
  71. *
  72. * Implementations of this method may obtain the name of the
  73. * actual folder using the <code>getFile()</code> method on
  74. * URLName, and use that name to create the folder.
  75. *
  76. * @param url URLName that denotes a folder
  77. * @see URLName
  78. * @exception IllegalStateException if this Store is not connected.
  79. * @return Folder object
  80. */
  81. public abstract Folder getFolder(URLName url)
  82. throws MessagingException;
  83. /**
  84. * Return a set of folders representing the <i>personal</i> namespaces
  85. * for the current user. A personal namespace is a set of names that
  86. * is considered within the personal scope of the authenticated user.
  87. * Typically, only the authenticated user has access to mail folders
  88. * in their personal namespace. If an INBOX exists for a user, it
  89. * must appear within the user's personal namespace. In the
  90. * typical case, there should be only one personal namespace for each
  91. * user in each Store. <p>
  92. *
  93. * This implementation returns an array with a single entry containing
  94. * the return value of the <code>getDefaultFolder</code> method.
  95. * Subclasses should override this method to return appropriate information.
  96. *
  97. * @exception IllegalStateException if this Store is not connected.
  98. * @return array of Folder objects
  99. * @since JavaMail 1.2
  100. */
  101. public Folder[] getPersonalNamespaces() throws MessagingException {
  102. return new Folder[] { getDefaultFolder() };
  103. }
  104. /**
  105. * Return a set of folders representing the namespaces for
  106. * <code>user</code>. The namespaces returned represent the
  107. * personal namespaces for the user. To access mail folders in the
  108. * other user's namespace, the currently authenticated user must be
  109. * explicitly granted access rights. For example, it is common for
  110. * a manager to grant to their secretary access rights to their
  111. * mail folders. <p>
  112. *
  113. * This implementation returns an empty array. Subclasses should
  114. * override this method to return appropriate information.
  115. *
  116. * @exception IllegalStateException if this Store is not connected.
  117. * @return array of Folder objects
  118. * @since JavaMail 1.2
  119. */
  120. public Folder[] getUserNamespaces(String user)
  121. throws MessagingException {
  122. return new Folder[0];
  123. }
  124. /**
  125. * Return a set of folders representing the <i>shared</i> namespaces.
  126. * A shared namespace is a namespace that consists of mail folders
  127. * that are intended to be shared amongst users and do not exist
  128. * within a user's personal namespace. <p>
  129. *
  130. * This implementation returns an empty array. Subclasses should
  131. * override this method to return appropriate information.
  132. *
  133. * @exception IllegalStateException if this Store is not connected.
  134. * @return array of Folder objects
  135. * @since JavaMail 1.2
  136. */
  137. public Folder[] getSharedNamespaces() throws MessagingException {
  138. return new Folder[0];
  139. }
  140. // Vector of Store listeners
  141. private volatile Vector storeListeners = null;
  142. /**
  143. * Add a listener for StoreEvents on this Store. <p>
  144. *
  145. * The default implementation provided here adds this listener
  146. * to an internal list of StoreListeners.
  147. *
  148. * @param l the Listener for Store events
  149. * @see javax.mail.event.StoreEvent
  150. */
  151. public synchronized void addStoreListener(StoreListener l) {
  152. if (storeListeners == null)
  153. storeListeners = new Vector();
  154. storeListeners.addElement(l);
  155. }
  156. /**
  157. * Remove a listener for Store events. <p>
  158. *
  159. * The default implementation provided here removes this listener
  160. * from the internal list of StoreListeners.
  161. *
  162. * @param l the listener
  163. * @see #addStoreListener
  164. */
  165. public synchronized void removeStoreListener(StoreListener l) {
  166. if (storeListeners != null)
  167. storeListeners.removeElement(l);
  168. }
  169. /**
  170. * Notify all StoreListeners. Store implementations are
  171. * expected to use this method to broadcast StoreEvents. <p>
  172. *
  173. * The provided default implementation queues the event into
  174. * an internal event queue. An event dispatcher thread dequeues
  175. * events from the queue and dispatches them to the registered
  176. * StoreListeners. Note that the event dispatching occurs
  177. * in a separate thread, thus avoiding potential deadlock problems.
  178. */
  179. protected void notifyStoreListeners(int type, String message) {
  180. if (storeListeners == null)
  181. return;
  182. StoreEvent e = new StoreEvent(this, type, message);
  183. queueEvent(e, storeListeners);
  184. }
  185. // Vector of folder listeners
  186. private volatile Vector folderListeners = null;
  187. /**
  188. * Add a listener for Folder events on any Folder object
  189. * obtained from this Store. FolderEvents are delivered to
  190. * FolderListeners on the affected Folder as well as to
  191. * FolderListeners on the containing Store. <p>
  192. *
  193. * The default implementation provided here adds this listener
  194. * to an internal list of FolderListeners.
  195. *
  196. * @param l the Listener for Folder events
  197. * @see javax.mail.event.FolderEvent
  198. */
  199. public synchronized void addFolderListener(FolderListener l) {
  200. if (folderListeners == null)
  201. folderListeners = new Vector();
  202. folderListeners.addElement(l);
  203. }
  204. /**
  205. * Remove a listener for Folder events. <p>
  206. *
  207. * The default implementation provided here removes this listener
  208. * from the internal list of FolderListeners.
  209. *
  210. * @param l the listener
  211. * @see #addFolderListener
  212. */
  213. public synchronized void removeFolderListener(FolderListener l) {
  214. if (folderListeners != null)
  215. folderListeners.removeElement(l);
  216. }
  217. /**
  218. * Notify all FolderListeners. Store implementations are
  219. * expected to use this method to broadcast Folder events. <p>
  220. *
  221. * The provided default implementation queues the event into
  222. * an internal event queue. An event dispatcher thread dequeues
  223. * events from the queue and dispatches them to the registered
  224. * FolderListeners. Note that the event dispatching occurs
  225. * in a separate thread, thus avoiding potential deadlock problems.
  226. *
  227. * @param type type of FolderEvent
  228. * @param folder affected Folder
  229. * @see #notifyFolderRenamedListeners
  230. */
  231. protected void notifyFolderListeners(int type, Folder folder) {
  232. if (folderListeners == null)
  233. return;
  234. FolderEvent e = new FolderEvent(this, folder, type);
  235. queueEvent(e, folderListeners);
  236. }
  237. /**
  238. * Notify all FolderListeners about the renaming of a folder.
  239. * Store implementations are expected to use this method to broadcast
  240. * Folder events indicating the renaming of folders. <p>
  241. *
  242. * The provided default implementation queues the event into
  243. * an internal event queue. An event dispatcher thread dequeues
  244. * events from the queue and dispatches them to the registered
  245. * FolderListeners. Note that the event dispatching occurs
  246. * in a separate thread, thus avoiding potential deadlock problems.
  247. *
  248. * @param oldF the folder being renamed
  249. * @param newF the folder representing the new name.
  250. * @since JavaMail 1.1
  251. */
  252. protected void notifyFolderRenamedListeners(Folder oldF, Folder newF) {
  253. if (folderListeners == null)
  254. return;
  255. FolderEvent e = new FolderEvent(this, oldF, newF,FolderEvent.RENAMED);
  256. queueEvent(e, folderListeners);
  257. }
  258. }