View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.geronimo.javamail.store.nntp;
21  
22  import java.io.File;
23  import java.io.PrintStream;
24  import java.util.Iterator;
25  
26  import javax.mail.Folder;
27  import javax.mail.MessagingException;
28  import javax.mail.Session;
29  import javax.mail.Store;
30  import javax.mail.URLName;
31  
32  import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrc;
33  import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcFile;
34  import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
35  import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
36  import org.apache.geronimo.javamail.util.ProtocolProperties; 
37  import org.apache.geronimo.mail.util.SessionUtil;
38  
39  /**
40   * NNTP implementation of javax.mail.Store POP protocol spec is implemented in
41   * org.apache.geronimo.javamail.store.pop3.NNTPConnection
42   * 
43   * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
44   */
45  public class NNTPStore extends Store {
46      protected static final String NNTP_NEWSRC = "newsrc";
47  
48      protected static final String protocol = "nntp";
49  
50      protected static final int DEFAULT_NNTP_PORT = 119;
51      protected static final int DEFAULT_NNTP_SSL_PORT = 563;
52  
53      // our accessor for protocol properties and the holder of 
54      // protocol-specific information 
55      protected ProtocolProperties props; 
56      // our active connection object (shared code with the NNTPStore).
57      protected NNTPConnection connection;
58  
59      // the root folder
60      protected NNTPRootFolder root;
61      // the newsrc file where we store subscriptions and seen message markers.
62      protected NNTPNewsrc newsrc;
63      
64      /**
65       * Construct an NNTPStore item. This will load the .newsrc file associated
66       * with the server.
67       * 
68       * @param session
69       *            The owning javamail Session.
70       * @param name
71       *            The Store urlName, which can contain server target
72       *            information.
73       */
74      public NNTPStore(Session session, URLName name) {
75          this(session, name, "nntp", DEFAULT_NNTP_PORT, false);
76      }
77  
78      /**
79       * Common constructor used by the POP3Store and POP3SSLStore classes
80       * to do common initialization of defaults.
81       *
82       * @param session
83       *            The host session instance.
84       * @param name
85       *            The URLName of the target.
86       * @param protocol
87       *            The protocol type ("nntp" or "nntps"). This helps us in
88       *            retrieving protocol-specific session properties.
89       * @param defaultPort
90       *            The default port used by this protocol. For pop3, this will
91       *            be 110. The default for pop3 with ssl is 995.
92       * @param sslConnection
93       *            Indicates whether an SSL connection should be used to initial
94       *            contact the server. This is different from the STARTTLS
95       *            support, which switches the connection to SSL after the
96       *            initial startup.
97       */
98      protected NNTPStore(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
99          super(session, name);
100         
101         // create the protocol property holder.  This gives an abstraction over the different 
102         // flavors of the protocol. 
103         props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
104 
105         // the connection manages connection for the transport 
106         connection = new NNTPConnection(props); 
107     }
108 
109     /**
110      * @see javax.mail.Store#getDefaultFolder()
111      * 
112      * This returns a root folder object for all of the news groups.
113      */
114     public Folder getDefaultFolder() throws MessagingException {
115         checkConnectionStatus();
116         if (root == null) {
117             return new NNTPRootFolder(this, connection.getHost(), connection.getWelcomeString());
118         }
119         return root;
120     }
121 
122     /**
123      * @see javax.mail.Store#getFolder(java.lang.String)
124      */
125     public Folder getFolder(String name) throws MessagingException {
126         return getDefaultFolder().getFolder(name);
127     }
128 
129     /**
130      * 
131      * @see javax.mail.Store#getFolder(javax.mail.URLName)
132      */
133     public Folder getFolder(URLName url) throws MessagingException {
134         return getDefaultFolder().getFolder(url.getFile());
135     }
136 
137     
138     /**
139      * Do the protocol connection for an NNTP transport. This handles server
140      * authentication, if possible. Returns false if unable to connect to the
141      * server.
142      * 
143      * @param host
144      *            The target host name.
145      * @param port
146      *            The server port number.
147      * @param user
148      *            The authentication user (if any).
149      * @param password
150      *            The server password. Might not be sent directly if more
151      *            sophisticated authentication is used.
152      * 
153      * @return true if we were able to connect to the server properly, false for
154      *         any failures.
155      * @exception MessagingException
156      */
157     protected boolean protocolConnect(String host, int port, String username, String password)
158             throws MessagingException {
159         // the connection pool handles all of the details here. But don't proceed 
160         // without a connection 
161         if (!connection.protocolConnect(host, port, username, password)) {
162             return false; 
163         }
164 
165         // see if we have a newsrc file location specified
166         String newsrcFile = props.getProperty(NNTP_NEWSRC);
167 
168         File source = null;
169 
170         // not given as a property? Then look for a file in user.home
171         if (newsrcFile != null) {
172             source = new File(newsrcFile);
173         } else {
174             // ok, look for a file in the user.home directory. If possible,
175             // we'll try for a file
176             // with the hostname appended.
177             String home = SessionUtil.getProperty("user.home");
178 
179             // try for a host-specific file first. If not found, use (and
180             // potentially create) a generic
181             // .newsrc file.
182             newsrcFile = ".newsrc-" + host;
183             source = new File(home, newsrcFile);
184             if (!source.exists()) {
185                 source = new File(home, ".newsrc");
186             }
187         }
188 
189         // now create a newsrc read and load the file.
190         newsrc = new NNTPNewsrcFile(source);
191         newsrc.load();
192 
193         // we're going to return success here, but in truth, the server may end
194         // up asking for our bonafides at any time, and we'll be expected to authenticate then.
195         return true;
196     }
197     
198 
199     /**
200      * @see javax.mail.Service#close()
201      */
202     public void close() throws MessagingException {
203         // This is done to ensure proper event notification.
204         super.close();
205         // persist the newsrc file, if possible
206         if (newsrc != null) {
207             newsrc.close();
208             newsrc = null; 
209         }
210         connection.close();
211         connection = null;
212     }
213 
214     private void checkConnectionStatus() throws MessagingException {
215         if (!this.isConnected()) {
216             throw new MessagingException("Not connected ");
217         }
218     }
219 
220     /**
221      * Retrieve the server connection created by this store.
222      * 
223      * @return The active connection object.
224      */
225     NNTPConnection getConnection() {
226         return connection;
227     }
228 
229     /**
230      * Retrieve the Session object this Store is operating under.
231      * 
232      * @return The attached Session instance.
233      */
234     Session getSession() {
235         return session;
236     }
237 
238     /**
239      * Retrieve all of the groups we nave persistent store information about.
240      * 
241      * @return The set of groups contained in the newsrc file.
242      */
243     Iterator getNewsrcGroups() {
244         return newsrc.getGroups();
245     }
246 
247     /**
248      * Retrieve the newsrc group information for a named group. If the file does
249      * not currently include this group, an unsubscribed group will be added to
250      * the file.
251      * 
252      * @param name
253      *            The name of the target group.
254      * 
255      * @return The NNTPNewsrcGroup item corresponding to this name.
256      */
257     NNTPNewsrcGroup getNewsrcGroup(String name) {
258         return newsrc.getGroup(name);
259     }
260 }