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 }