зеркало из https://github.com/mozilla/pjs.git
298 строки
7.8 KiB
Java
298 строки
7.8 KiB
Java
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License
|
|
* Version 1.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.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
* the License for the specific language governing rights and limitations
|
|
* under the License.
|
|
*
|
|
* The Original Code is the Grendel mail/news client.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1997
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
*
|
|
* Created: Jamie Zawinski <jwz@netscape.com>, 20 Nov 1997.
|
|
*/
|
|
|
|
package grendel.storage;
|
|
|
|
import calypso.util.Assert;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.awt.Component;
|
|
import java.net.URL;
|
|
import java.net.UnknownHostException;
|
|
|
|
import javax.mail.Folder;
|
|
import javax.mail.Message;
|
|
import javax.mail.MessagingException;
|
|
import javax.mail.Session;
|
|
import javax.mail.Store;
|
|
import javax.mail.URLName;
|
|
//import javax.mail.event.ConnectionEvent;
|
|
import javax.mail.event.StoreEvent;
|
|
|
|
|
|
/** Store for News (NNTP) folders.
|
|
<p>
|
|
This class really shouldn't be public, but I haven't figured out how to
|
|
tie into javamail's Session class properly. So, instead of using
|
|
<tt>Session.getStore(String)</tt>, you instead need to call
|
|
<tt>NewsStore.GetDefaultStore(Session)</tt>.
|
|
*/
|
|
|
|
public class NewsStore extends Store {
|
|
|
|
protected NNTPConnection nntp = null;
|
|
protected NewsRC newsrc = null;
|
|
protected NewsFolderRoot root_folder = null;
|
|
|
|
static protected NewsStore DefaultStore = null;
|
|
|
|
public static Store GetDefaultStore(Session s) {
|
|
if (DefaultStore == null) {
|
|
DefaultStore = new NewsStore(s);
|
|
}
|
|
return DefaultStore;
|
|
}
|
|
|
|
|
|
public NewsStore(Session s) {
|
|
super(s, null);
|
|
}
|
|
|
|
public NewsStore(Session s, URLName u) {
|
|
super(s, u);
|
|
}
|
|
|
|
NewsRC getNewsRC() {
|
|
return newsrc;
|
|
}
|
|
|
|
private void loadNewsRC(String host) throws IOException {
|
|
Assert.Assertion(newsrc == null);
|
|
String dir = System.getProperty("user.home");
|
|
boolean secure = false; // ####
|
|
String name = null;
|
|
|
|
if (Constants.ISUNIX) {
|
|
|
|
String name1 = (secure ? ".snewsrc" : ".newsrc");
|
|
String name2 = name1 + "-" + host;
|
|
if (new File(dir, name2).exists())
|
|
name = name2;
|
|
else if (new File(dir, name1).exists())
|
|
name = name1;
|
|
else
|
|
name = name2;
|
|
|
|
} else if (Constants.ISWINDOWS) {
|
|
|
|
String name1 = (secure ? "snews" : "news");
|
|
String name2 = name1 + "-" + host + ".rc";
|
|
String name3 = name1 + ".rc";
|
|
if (new File(dir, name2).exists())
|
|
name = name2;
|
|
else if (new File(dir, name3).exists())
|
|
name = name3;
|
|
else
|
|
name = name2;
|
|
|
|
} else {
|
|
Assert.NotYetImplemented("newsrc names only implemented for windows 'n' unix...");
|
|
}
|
|
|
|
File f = new File(dir, name);
|
|
newsrc = new NewsRC(f);
|
|
|
|
// If the newsrc file didn't exist, subscribe to some default newsgroups.
|
|
if (!f.exists()) {
|
|
String subs[] = getDefaultSubscriptions();
|
|
for (int i = 0; i < subs.length; i++) {
|
|
NewsRCLine ng = newsrc.getNewsgroup(subs[i]);
|
|
ng.setSubscribed(true);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
protected boolean protocolConnect(String host,
|
|
String user,
|
|
String password)
|
|
throws MessagingException {
|
|
|
|
if (nntp != null)
|
|
return true; // Already connected.
|
|
|
|
if (host == null) {
|
|
// #### better name?
|
|
host = session.getProperty("mail.default_nntp_server");
|
|
if (host == null || host == "") {
|
|
// #### pop up a dialog box instead?
|
|
host = "news";
|
|
}
|
|
}
|
|
|
|
try {
|
|
loadNewsRC(host);
|
|
} catch (IOException e) {
|
|
throw new MessagingException("loading newsrc file", e);
|
|
}
|
|
|
|
nntp = new NNTPConnection();
|
|
|
|
int port = -1; // #### override this from the url or something.
|
|
|
|
try {
|
|
boolean status = nntp.connect(host, port, user, password);
|
|
if (!status) return false;
|
|
|
|
} catch (UnknownHostException e) { // This sucks, Beavis!
|
|
throw new MessagingException("Unknown host", e);
|
|
} catch (IOException e) {
|
|
throw new MessagingException("I/O Error", e);
|
|
}
|
|
|
|
if (!newsrc.file().exists()) {
|
|
// #### subscribe to the server's default groups
|
|
}
|
|
|
|
notifyStoreListeners(StoreEvent.NOTICE, "opened"); // #### ???
|
|
// notifyConnectionListeners(ConnectionEvent.OPENED);
|
|
return true;
|
|
}
|
|
|
|
public void close() {
|
|
|
|
if (nntp == null) {
|
|
// already closed.
|
|
Assert.Assertion(newsrc == null);
|
|
return;
|
|
}
|
|
|
|
nntp.close();
|
|
nntp = null;
|
|
|
|
Assert.Assertion(newsrc != null);
|
|
if (newsrc != null) {
|
|
try {
|
|
newsrc.save();
|
|
} catch (IOException e) {
|
|
// Sun doesn't allow us to signal here. Bastards...
|
|
// Just ignore it, I guess...
|
|
}
|
|
}
|
|
|
|
notifyStoreListeners(StoreEvent.NOTICE, "closed"); // #### ???
|
|
// notifyConnectionListeners(ConnectionEvent.CLOSED);
|
|
root_folder = null;
|
|
}
|
|
|
|
|
|
public Folder getDefaultFolder() {
|
|
if (root_folder == null) {
|
|
synchronized (this) {
|
|
if (root_folder == null) { // double check
|
|
root_folder = new NewsFolderRoot(this);
|
|
}
|
|
}
|
|
}
|
|
return root_folder;
|
|
}
|
|
|
|
public Folder getFolder(String name) throws MessagingException {
|
|
return getDefaultFolder().getFolder(name);
|
|
}
|
|
|
|
public Folder getFolder(URL url) {
|
|
Assert.NotYetImplemented("NewsStore.getFolder(URL)");
|
|
return null;
|
|
}
|
|
|
|
public Folder getFolder(URLName urlName) {
|
|
Assert.NotYetImplemented("NewsStore.getFolder(URLName)");
|
|
return null;
|
|
}
|
|
|
|
InputStream getMessageStream(NewsMessage message, boolean headers_too)
|
|
throws NNTPException, IOException {
|
|
Folder f = message.getFolder();
|
|
String group = (f == null ? null : f.getFullName());
|
|
int n = (group == null ? -1 : message.getStorageFolderIndex());
|
|
if (n == -1) {
|
|
/*
|
|
String id = #### ;
|
|
if (headers_too)
|
|
return nntp.ARTICLE(id);
|
|
else
|
|
return nntp.BODY(id);
|
|
*/
|
|
Assert.NotYetImplemented("NewsStore.getMessageStream via Message-ID");
|
|
return null;
|
|
} else {
|
|
if (headers_too)
|
|
return nntp.ARTICLE(group, n);
|
|
else
|
|
return nntp.BODY(group, n);
|
|
}
|
|
}
|
|
|
|
/** Returns array of int: [ nmessages low hi ]
|
|
*/
|
|
int[] getGroupCounts(NewsFolder folder) {
|
|
String group = folder.getFullName();
|
|
try {
|
|
return nntp.GROUP(group);
|
|
} catch (IOException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/** Returns a list of newsgroups to which new users should be subscribed,
|
|
if they don't have a newsrc file. Tries to ask the news server for
|
|
this list; otherwise, uses some builtin defaults.
|
|
*/
|
|
String[] getDefaultSubscriptions() {
|
|
String s[] = null;
|
|
try {
|
|
s = nntp.LIST_SUBSCRIPTIONS();
|
|
} catch (NNTPException e) { // command unsupported
|
|
} catch (IOException e) { // something else
|
|
}
|
|
if (s == null || s.length == 0)
|
|
s = new String[] { "news.announce.newusers",
|
|
"news.newusers.questions",
|
|
"news.groups.questions",
|
|
"alt.fan.mozilla"
|
|
};
|
|
return s;
|
|
}
|
|
|
|
void openNewsgroup(NewsFolder folder, long from, long to) {
|
|
Enumeration e;
|
|
try {
|
|
e = nntp.getMessages(folder, from, to);
|
|
} catch (NNTPException ex) {
|
|
return;
|
|
} catch (IOException ex) {
|
|
return;
|
|
}
|
|
|
|
while (e.hasMoreElements()) {
|
|
Message m = (Message) e.nextElement();
|
|
folder.noticeInitialMessage(m);
|
|
}
|
|
}
|
|
}
|