GNU NNTPを使用して、ローカルホスト上の NNTP サーバーであるleafnodeに接続しています。GNU API は を使用しますjavax.mail.Message
が、これには次の注意事項があります。
メッセージ APIから:
..特定のメッセージのメッセージ番号は、フォルダ内の他のメッセージが削除および消去された場合、セッション中に変更される可能性があります。
そのため、現在、javax.mail.search
既知のメッセージを検索するために使用しています。残念ながら、各検索でフォルダ全体が検索されました。フォルダを開いたままにしておくことで、検索を少し高速化できますが、扱いにくいようです。
を使用する別の方法はjavax.mail.search
何ですか? これ:
SearchTerm st = new MessageIDTerm(id);
List<Message> messages = Arrays.asList(folder.search(st));
javax.mail.Folder
に数個しかない場合は正常に動作しMessage
ます。ただし、 が非常に大きいFolder
場合は、より適切なアプローチが必要です。Message-ID
ヘッダー フィールドの代わりに、Xref
好ましいかもしれませんが、文字列を検索するという同じ基本的な問題があります。
Folder
指定されたメッセージの を検索/取得/検索するのに十分な情報を保持する必要があるデータベースは次のとおりです。
mysql>
mysql> use usenet;show tables;
Database changed
+------------------+
| Tables_in_usenet |
+------------------+
| articles |
| newsgroups |
+------------------+
2 rows in set (0.00 sec)
mysql>
mysql> describe articles;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| ID | bigint(20) | NO | PRI | NULL | auto_increment |
| MESSAGEID | varchar(255) | YES | | NULL | |
| NEWSGROUP_ID | bigint(20) | YES | MUL | NULL | |
+--------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql>
mysql> describe newsgroups;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| ID | bigint(20) | NO | PRI | NULL | auto_increment |
| NEWSGROUP | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql>
スキーマは現時点では非常に単純ですが、さらに複雑にする予定です。
メッセージは次のように照会されますgetMessage()
:
package net.bounceme.dur.usenet.model;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.*;
import javax.mail.search.MessageIDTerm;
import javax.mail.search.SearchTerm;
import net.bounceme.dur.usenet.controller.Page;
public enum Usenet {
INSTANCE;
private final Logger LOG = Logger.getLogger(Usenet.class.getName());
private Properties props = new Properties();
private Folder root = null;
private Store store = null;
private List<Folder> folders = new ArrayList<>();
private Folder folder = null;
Usenet() {
LOG.fine("controller..");
props = PropertiesReader.getProps();
try {
connect();
} catch (Exception ex) {
Logger.getLogger(Usenet.class.getName()).log(Level.SEVERE, "FAILED TO LOAD MESSAGES", ex);
}
}
public void connect() throws Exception {
LOG.fine("Usenet.connect..");
Session session = Session.getDefaultInstance(props);
session.setDebug(true);
store = session.getStore(new URLName(props.getProperty("nntp.host")));
store.connect();
root = store.getDefaultFolder();
setFolders(Arrays.asList(root.listSubscribed()));
}
public List<Message> getMessages(Page page) throws Exception {
Newsgroup newsgroup = new Newsgroup(page);
LOG.fine("fetching.." + newsgroup);
folder = root.getFolder(newsgroup.getNewsgroup());
folder.open(Folder.READ_ONLY);
List<Message> messages = Arrays.asList(folder.getMessages());
LOG.fine("..fetched " + folder);
return Collections.unmodifiableList(messages);
}
public List<Folder> getFolders() {
LOG.fine("folders " + folders);
return Collections.unmodifiableList(folders);
}
private void setFolders(List<Folder> folders) {
this.folders = folders;
}
public Message getMessage(Newsgroup newsgroup, Article article) throws MessagingException {
LOG.fine("\n\ntrying.." + newsgroup + article);
String id = article.getMessageId();
Message message = null;
folder = root.getFolder(newsgroup.getNewsgroup());
folder.open(Folder.READ_ONLY);
SearchTerm st = new MessageIDTerm(id);
List<Message> messages = Arrays.asList(folder.search(st));
LOG.severe(messages.toString());
if (!messages.isEmpty()) {
message = messages.get(0);
}
LOG.info(message.getSubject());
return message;
}
}
私が今気付いている問題は、次のことです。
...the message number for a particular Message can change during a session if other messages in the Folder are deleted and expunged.
どの特定のヘッダーが使用されているかに関係なく、次のようなものです。
Message-ID: <x1-CZwog1NTZLd68+JJY35Zrl9OqXE@gwene.org>
また
Xref: dur.bounceme.net gwene.com.economist:541
そのため、解析と検索が必要な文字列が常に存在するため、これは非常に厄介です。
MimeMessage
非常に便利なgetMessageIDメソッドがあることに気付きました。残念ながら、GNU はjavax.mail.Message
and ではなくを使用しMimeMessage
ます。確かに、フォルダーとをインスタンス化することは可能ですが、ある実行から別の実行に至るまで、正しいメッセージが返さMimeMessage
れるという保証はありません。getMessageID
私が見る厄介な解決策は、おそらくの永続的なフォルダーを作成するMimeMessage
ことですが、それはやり過ぎのようです。
したがって、ヘッダーを使用して、Xref
またはMessage-ID
文字列を解析して検索します...
より良い方法はありますか?