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 }