2012-08-12 102 views
0

我使用GNU NNTP連接到本地主機上的NNTP服務器leafnode。在GNU API利用javax.mail.Message,附帶以下警告:是否有替代javax.mail.search?

Message API

用於特定消息的 會話期間可以改變..the消息號,如果在文件夾的其他消息都將被刪除並被清除。

所以,目前,我正在使用javax.mail.search來搜索已知消息。不幸的是,對於每個搜索,整個文件夾都被搜索到了。我可以保持文件夾打開,並以這種方式加快搜索速度,但它似乎klunky。

什麼是替代方法使用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: <[email protected]> 

Xref: dur.bounceme.net gwene.com.economist:541 

因此總會有一個需要解析和搜索的字符串,這非常尷尬。

我注意到MimeMessage有一個非常方便的getMessageID方法。不幸的是,GNU使用javax.mail.Message而不是MimeMessage。當然,有可能實例化一個文件夾和MimeMessage,但我沒有看到從一次運行到另一次的任何節省,不能保證getMessageID將返回正確的消息。

我看到的尷尬解決方案是可能創建一個MimeMessage的持久性文件夾,但這似乎是矯枉過正。

因此,使用標頭,XrefMessage-ID,然後解析和搜索字符串...

有沒有更好的方法?

回答

2

javax.mail是一個最低公因分母API,它的行爲完全取決於後端是什麼。所以,不知道你在說什麼,對你的問題提供一個很好的答案是不可能的。然而,有可能你需要直接與你談話的任何事情交談,並且更多地瞭解它的行爲。

這可能是一個評論,而不是一個答案,但我認爲這個API只是一個薄層的信息可能是足夠的信息來證明。

+0

我正在使用GNU NNTP庫與在本地主機上運行的葉節點NNTP服務器進行通信。特赦,忘了包括那個,我試圖簡潔。我會更新我的問題。 – Thufir 2012-08-12 22:49:54