blob: b69bea40f0ba7bec89de0c078087c597d1d1d233 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.geronimo.javamail.store.nntp;
import java.io.File;
import java.io.PrintStream;
import java.util.Iterator;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrc;
import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcFile;
import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
import org.apache.geronimo.mail.util.SessionUtil;
/**
* NNTP implementation of javax.mail.Store POP protocol spec is implemented in
* org.apache.geronimo.javamail.store.pop3.NNTPConnection
*
* @version $Rev$ $Date$
*/
public class NNTPStore extends Store {
protected static final String NNTP_AUTH = "auth";
protected static final String NNTP_PORT = "port";
protected static final String NNTP_NEWSRC = "newsrc";
protected static final String protocol = "nntp";
protected static final int DEFAULT_NNTP_PORT = 119;
// the active connection object.
protected NNTPConnection connection;
// the newsrc file where we store subscriptions and seen message markers.
protected NNTPNewsrc newsrc;
// the root folder
protected NNTPRootFolder root;
// our session provided debug output stream.
protected PrintStream debugStream;
/**
* Construct an NNTPStore item. This will load the .newsrc file associated
* with the server.
*
* @param session
* The owning javamail Session.
* @param urlName
* The Store urlName, which can contain server target
* information.
*/
public NNTPStore(Session session, URLName urlName) {
super(session, urlName);
// get our debug output.
debugStream = session.getDebugOut();
}
/**
* @see javax.mail.Store#getDefaultFolder()
*
* This returns a root folder object for all of the news groups.
*/
public Folder getDefaultFolder() throws MessagingException {
checkConnectionStatus();
if (root == null) {
return new NNTPRootFolder(this, connection.getHost(), connection.getWelcomeString());
}
return root;
}
/**
* @see javax.mail.Store#getFolder(java.lang.String)
*/
public Folder getFolder(String name) throws MessagingException {
return getDefaultFolder().getFolder(name);
}
/**
*
* @see javax.mail.Store#getFolder(javax.mail.URLName)
*/
public Folder getFolder(URLName url) throws MessagingException {
return getDefaultFolder().getFolder(url.getFile());
}
/**
* @see javax.mail.Service#protocolConnect(java.lang.String, int,
* java.lang.String, java.lang.String)
*/
protected synchronized boolean protocolConnect(String host, int port, String username, String password)
throws MessagingException {
if (debug) {
debugOut("Connecting to server " + host + ":" + port + " for user " + username);
}
// first check to see if we need to authenticate. If we need this, then
// we must have a username and
// password specified. Failing this may result in a user prompt to
// collect the information.
boolean mustAuthenticate = getBooleanProperty(NNTP_AUTH, false);
// if we need to authenticate, and we don't have both a userid and
// password, then we fail this
// immediately. The Service.connect() method will try to obtain the user
// information and retry the
// connection one time.
if (mustAuthenticate && (username == null || password == null)) {
return false;
}
// if the port is defaulted, then see if we have something configured in
// the session.
// if not configured, we just use the default default.
if (port == -1) {
// check for a property and fall back on the default if it's not
// set.
port = getIntProperty(NNTP_PORT, DEFAULT_NNTP_PORT);
}
// create socket and connect to server.
connection = new NNTPConnection(protocol, session, host, port, username, password, debug);
connection.connect();
// see if we have a newsrc file location specified
String newsrcFile = getProperty(NNTP_NEWSRC);
File source = null;
// not given as a property? Then look for a file in user.home
if (newsrcFile != null) {
source = new File(newsrcFile);
} else {
// ok, look for a file in the user.home directory. If possible,
// we'll try for a file
// with the hostname appended.
String home = SessionUtil.getProperty("user.home");
// try for a host-specific file first. If not found, use (and
// potentially create) a generic
// .newsrc file.
newsrcFile = ".newsrc-" + host;
source = new File(home, newsrcFile);
if (!source.exists()) {
source = new File(home, ".newsrc");
}
}
// now create a newsrc read and load the file.
newsrc = new NNTPNewsrcFile(source);
newsrc.load();
// we're going to return success here, but in truth, the server may end
// up asking for our
// bonafides at any time, and we'll be expected to authenticate then.
return true;
}
/**
* @see javax.mail.Service#close()
*/
public void close() throws MessagingException {
// This is done to ensure proper event notification.
super.close();
// persist the newsrc file, if possible
newsrc.close();
connection.close();
connection = null;
}
private void checkConnectionStatus() throws MessagingException {
if (!this.isConnected()) {
throw new MessagingException("Not connected ");
}
}
/**
* Internal debug output routine.
*
* @param value
* The string value to output.
*/
void debugOut(String message) {
debugStream.println("NNTPTransport DEBUG: " + message);
}
/**
* Internal debugging routine for reporting exceptions.
*
* @param message
* A message associated with the exception context.
* @param e
* The received exception.
*/
void debugOut(String message, Throwable e) {
debugOut("Received exception -> " + message);
debugOut("Exception message -> " + e.getMessage());
e.printStackTrace(debugStream);
}
/**
* Retrieve the server connection created by this store.
*
* @return The active connection object.
*/
NNTPConnection getConnection() {
return connection;
}
/**
* Retrieve the Session object this Store is operating under.
*
* @return The attached Session instance.
*/
Session getSession() {
return session;
}
/**
* Retrieve all of the groups we nave persistent store information about.
*
* @return The set of groups contained in the newsrc file.
*/
Iterator getNewsrcGroups() {
return newsrc.getGroups();
}
/**
* Retrieve the newsrc group information for a named group. If the file does
* not currently include this group, an unsubscribed group will be added to
* the file.
*
* @param name
* The name of the target group.
*
* @return The NNTPNewsrcGroup item corresponding to this name.
*/
NNTPNewsrcGroup getNewsrcGroup(String name) {
return newsrc.getGroup(name);
}
/**
* Get a property associated with this mail protocol.
*
* @param name
* The name of the property.
*
* @return The property value (returns null if the property has not been
* set).
*/
String getProperty(String name) {
// the name we're given is the least qualified part of the name. We
// construct the full property name
// using the protocol (either "nntp" or "nntp-post").
String fullName = "mail." + protocol + "." + name;
return session.getProperty(fullName);
}
/**
* Get a property associated with this mail session. Returns the provided
* default if it doesn't exist.
*
* @param name
* The name of the property.
* @param defaultValue
* The default value to return if the property doesn't exist.
*
* @return The property value (returns defaultValue if the property has not
* been set).
*/
String getProperty(String name, String defaultValue) {
// the name we're given is the least qualified part of the name. We
// construct the full property name
// using the protocol (either "nntp" or "nntp-post").
String fullName = "mail." + protocol + "." + name;
return SessionUtil.getProperty(session, fullName, defaultValue);
}
/**
* Get a property associated with this mail session as an integer value.
* Returns the default value if the property doesn't exist or it doesn't
* have a valid int value.
*
* @param name
* The name of the property.
* @param defaultValue
* The default value to return if the property doesn't exist.
*
* @return The property value converted to an int.
*/
int getIntProperty(String name, int defaultValue) {
// the name we're given is the least qualified part of the name. We
// construct the full property name
// using the protocol (either "nntp" or "nntp-post").
String fullName = "mail." + protocol + "." + name;
return SessionUtil.getIntProperty(session, fullName, defaultValue);
}
/**
* Get a property associated with this mail session as an boolean value.
* Returns the default value if the property doesn't exist or it doesn't
* have a valid int value.
*
* @param name
* The name of the property.
* @param defaultValue
* The default value to return if the property doesn't exist.
*
* @return The property value converted to a boolean
*/
boolean getBooleanProperty(String name, boolean defaultValue) {
// the name we're given is the least qualified part of the name. We
// construct the full property name
// using the protocol (either "nntp" or "nntp-post").
String fullName = "mail." + protocol + "." + name;
return SessionUtil.getBooleanProperty(session, fullName, defaultValue);
}
}