📄 messageindex.java
字号:
/*
* MessageIndex.java
*
* Copyright (C) 1998-2000 FreeBeans <freebeans@mub.biglobe.ne.jp>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) 1998-2000擭 FreeBeans <freebeans@mub.biglobe.ne.jp>
*
* 杮僾儘僌儔儉偼僼儕乕丒僜僼僩僂僃傾偱偡丅偁側偨偼丄Free Software Foundation
* 偑岞昞偟偨GNU 堦斒岞桳巊梡嫋戻偺乽僶乕僕儑儞俀乿埥偄偼偦傟埲崀偺奺僶乕僕儑
* 儞偺拞偐傜偄偢傟偐傪慖戰偟丄偦偺僶乕僕儑儞偑掕傔傞忦崁偵廬偭偰杮僾儘僌儔儉
* 傪嵞斝晍傑偨偼曄峏偡傞偙偲偑偱偒傑偡丅
* 杮僾儘僌儔儉偼桳梡偲偼巚偄傑偡偑丄斝晍偵偁偨偭偰偼丄巗応惈媦傃摿掕栚揑揔崌
* 惈偵偮偄偰偺埫栙偺曐徹傪娷傔偰丄偄偐側傞曐徹傕峴側偄傑偣傫丅徻嵶偵偮偄偰偼
* GNU 堦斒岞桳巊梡嫋戻彂傪偍撉傒偔偩偝偄丅
*
* 偁側偨偼丄杮僾儘僌儔儉偲堦弿偵GNU 堦斒岞桳巊梡嫋戻偺幨偟傪庴偗庢偭偰偄
* 傞偼偢偱偡丅偦偆偱側偄応崌偼丄Free Software Foundation, Inc., 675 Mass Ave,
* Cambridge, MA 02139, USA 傊庤巻傪彂偄偰偔偩偝偄丅
*/
package jp.gr.java_conf.roadster.net.pop;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;
import java.util.WeakHashMap;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetHeaders;
/**
* 儊僢僙乕僕僼傽僀儖傪娗棟偡傞僋儔僗.
* 侾偮偺暔棟僨傿儗僋僩儕偵懳偟偰丄侾偮偺僀儞僗僞儞僗偑懚嵼偡傞.
* 侾偮偺暔棟僨傿儗僋僩儕偵懳偟偰丄暋悢偺 POP3Folder 僀儞僗僞儞僗偑
* 懚嵼偡傞応崌偵傕丄偙偺僋儔僗偱僼傽僀儖傊偺傾僋僙僗傪摨婜壔偡傞.
*/
public class MessageIndex {
/**
* 僀儞僨僢僋僗僼傽僀儖柤.
*/
private static final String INDEX_FILE_NAME = "folder.idx";
/**
* 僨乕僞僼傽僀儖柤偺僒僼傿僢僋僗.
*/
private static final String DATA_FILE_SUFFIX = ".dat";
/**
* 擖弌椡僶僢僼傽偺僒僀僘.(=16KB)
*/
private static final int BUFFER_SIZE = 16 * 1024;
/**
* 僀儞僗僞儞僗.
* 侾偮偺僨傿儗僋僩儕偵懳偟偰丄俀偮埲忋偺僀儞僗僞儞僗偑
* 懚嵼偟側偄傛偆偵惂屼偟偰偄傞.
*/
private static Hashtable instances = new Hashtable();
/**
* 曐懚梡僶僢僋僌儔僂儞僪僗儗僢僪.
* 慡僀儞僗僞儞僗偺僨乕僞傪丄侾偮偺僶僢僋僌儔僂儞僪僗儗僢僪偱曐懚偡傞.
*/
private static SaverThread saverThread;
/**
* 僨乕僞僨傿儗僋僩儕.
*/
private File dataDirectory;
/**
* 僀儞僨僢僋僗僼傽僀儖.
*/
private File indexFile;
/**
* 僀儞僨僢僋僗杮懱.
*/
private Vector elements;
/**
* 僨乕僞傪僉儍僢僔儏偟偰偍偔WeakHashMap 僆僽僕僃僋僩丅
* MessageIndexElement傪僉乕偵偟偰丄InternetHeaders 僆僽僕僃僋僩傪僉儍僢僔儏偟偰偄傞丅
*/
private static HashMap<String,SerializableInternetHeaders> HEADERS_MAP=new HashMap<String,SerializableInternetHeaders>();
/**
* 僨乕僞傪僉儍僢僔儏偟偰偍偔WeakHashMap 僆僽僕僃僋僩丅
* MessageIndexElement傪僉乕偵偟偰丄byte[] 僆僽僕僃僋僩乮content乯傪僉儍僢僔儏偟偰偄傞丅
*/
private static final WeakHashMap CONTENT_MAP=new WeakHashMap();
private static boolean cacheContent=true; //是否对内容进行缓存,搜索时不缓存
/**
* 巜掕偝傟偨僨傿儗僋僩儕撪偺僼傽僀儖傪娗棟偡傞
* MessageIndex 偺僀儞僗僞儞僗傪嶌惉偡傞.
* 偙偺僐儞僗僩儔僋僞傪屇傃弌偡偙偲偼偱偒側偄.
* MessageIndex 偺僀儞僗僞儞僗偼丄getInstance() 儊僜僢僪傪屇傃弌偟偰嶌惉偡傞.
*
* @param dataDirectory 娗棟懳徾偲側傞僨傿儗僋僩儕.
* @see #getInstance(java.io.File)
*/
private MessageIndex(File dataDirectory) {
try {
this.dataDirectory = dataDirectory;
indexFile = new File(dataDirectory, INDEX_FILE_NAME);
load();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* 巜掕偝傟偨僨傿儗僋僩儕偵懳墳偡傞 MessageIndex 偺僀儞僗僞儞僗傪摼傞.
*
* @param dataDirectory 娗棟懳徾偲側傞僨傿儗僋僩儕.
*/
public static synchronized MessageIndex getInstance(File dataDirectory) {
if (saverThread == null) {
saverThread = new SaverThread();
saverThread.start();
}
MessageIndex mfi = (MessageIndex) instances.get(dataDirectory);
if (mfi == null) {
mfi = new MessageIndex(dataDirectory);
instances.put(dataDirectory, mfi);
}
return mfi;
}
/**
* 僼傿乕儖僪 elements 傪弶婜壔偡傞.
*/
public synchronized void initElements() {
if (elements == null) {
elements = new Vector();
elements.addElement(INDEX_FILE_NAME); // 0斣栚偺梫慺偼巊傢側偄.
} else {
elements.setSize(1);
}
}
/**
* 巜掕偝傟偨僼僅儖僟偵強懏偟丄巜掕偝傟偨儊僢僙乕僕斣崋傪帩偮 POP3Message 偺僀儞僗僞儞僗傪嶌惉偡傞.
*
* @param folder POP3Folder 偺僀儞僗僞儞僗.
* @param msgnum 儊僢僙乕僕斣崋.
* @exception java.lang.IndexOutOfBoundsException msgnum 偑斖埻傪挻偊偰偄傞応崌.
*/
public synchronized POP3Message createMessage(POP3Folder folder, int msgnum) throws MessagingException {
POP3Message message = new POP3Message(folder, msgnum);
message.setInternalID(elements.elementAt(msgnum));
return message;
}
/**
* 巜掕偝傟偨儊僢僙乕僕偵懳墳偡傞儊僢僙乕僕僨乕僞偺擖椡僗僩儕乕儉傪摼傞.
*
* @param message 儊僢僙乕僕.
* @return 擖椡僗僩儕乕儉.
* @exception java.io.IOException 僄儔乕偑敪惗偟偨応崌.
*/
private synchronized InputStream getInputStream(POP3Message message) throws IOException {
MessageIndexElement mie = (MessageIndexElement) message.getInternalID();
return new BufferedInputStream(mie.getInputStream(dataDirectory), BUFFER_SIZE);
}
/**
* 巜掕偝傟偨儊僢僙乕僕偺InternetHeaders傪曉偡丅
* Java2娐嫬壓偱偼僨傿僗僋俬乛俷傪尭傜偡偨傔偵丄撉傒崬傫偩僨乕僞傪僉儍僢僔儏偡傞丅
* 僉儍僢僔儏偼儊儌儕儕乕僋偑敪惗偟側偄傛偆偵丄WeakHashMap傪巊偭偰偄傞偨傔丄JDK1.1娐嫬壓偱偼僉儍僢僔儏偝傟側偄丅
* JDK1.1娐嫬壓偱偼丄忢偵怴偟偄僆僽僕僃僋僩偑new偝傟傞丅
*
* @param message 儊僢僙乕僕丅
* @return InternetHeaders
* @throws javax.mail.MessagingException 僄儔乕偑敪惗偟偨応崌丅
*/
public synchronized InternetHeaders getHeaders(POP3Message message) throws MessagingException {
SerializableInternetHeaders ret = null;
MessageIndexElement mie = (MessageIndexElement) message.getInternalID();
try {
if (HEADERS_MAP != null) {
synchronized (HEADERS_MAP) {
ret = (SerializableInternetHeaders) HEADERS_MAP.get(mie.getFileName());
}
}
if (ret == null) { // 僉儍僢僔儏偝傟偰偄側偐偭偨応崌丄怴偨偵撉傒偙傓丅
InputStream is = getInputStream(message);
ret = new SerializableInternetHeaders(is);
is.close();
if (HEADERS_MAP != null) { // 撉傒偙傫偩寢壥傪僉儍僢僔儏偡傞丅
synchronized (HEADERS_MAP) {
HEADERS_MAP.put(mie.getFileName(), ret);
}
}
}
} catch (IOException ioe) {
throw new MessagingException("IOException", ioe);
}
return ret;
}
/**
* 巜掕偝傟偨儊僢僙乕僕偺content傪昞偡 byte[] 傪曉偡丅
* Java2娐嫬壓偱偼僨傿僗僋俬乛俷傪尭傜偡偨傔偵丄撉傒崬傫偩僨乕僞傪僉儍僢僔儏偡傞丅
* 僉儍僢僔儏偼儊儌儕儕乕僋偑敪惗偟側偄傛偆偵丄WeakHashMap傪巊偭偰偄傞偨傔丄JDK1.1娐嫬壓偱偼僉儍僢僔儏偝傟側偄丅
* JDK1.1娐嫬壓偱偼丄忢偵怴偟偄僆僽僕僃僋僩偑new偝傟傞丅
*
* @param message 儊僢僙乕僕丅
* @return content傪昞偡byte[]
* @throws javax.mail.MessagingException 僄儔乕偑敪惗偟偨応崌丅
*/
public synchronized byte[] getContentBytes(POP3Message message) throws MessagingException {
byte[] ret = null;
MessageIndexElement mie = (MessageIndexElement) message.getInternalID();
try {
if (CONTENT_MAP != null) {
synchronized (CONTENT_MAP) {
ret = (byte[]) CONTENT_MAP.get(mie);
}
}
if (ret == null) { // 僉儍僢僔儏偝傟偰偄側偐偭偨応崌丄怴偨偵撉傒偙傓丅
InputStream is = getInputStream(message);
InternetHeaders headers = new SerializableInternetHeaders(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[16 * 1024];
int len;
while ((len = is.read(buff)) != -1) {
baos.write(buff, 0, len);
}
is.close();
baos.close();
ret = baos.toByteArray();
if (CONTENT_MAP != null && cacheContent) { // 撉傒偙傫偩寢壥傪僉儍僢僔儏偡傞丅
synchronized (CONTENT_MAP) {
CONTENT_MAP.put(mie, ret);
}
}
}
} catch (IOException ioe) {
throw new MessagingException("IOException", ioe);
}
return ret;
}
/**
* 儊僢僙乕僕傪僀儞僨僢僋僗偵捛壛偡傞.
* 奺Message偺isExpunged()偑true傪曉偟偨応崌偵偼丄偦偺儊僢僙乕僕偼僗僉僢僾偝傟傞丅
*
* @param msgs 捛壛偡傞儊僢僙乕僕偺攝楍.
* 儊僢僙乕僕斣崋偼柍帇偝傟丄昁偢枛旜偵捛壛偝傟傞.
*/
public synchronized void append(Message msgs[]) {
for (int i = 0; i < msgs.length; ++i) {
try {
Message message = msgs[i];
if (! message.isExpunged()) {
File file = createMessageFile();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file), BUFFER_SIZE);
message.writeTo(bos);
bos.close();
MessageIndexElement mie = new MessageIndexElement();
mie.setFileName(file.getName());
mie.setFlags(message.getFlags());
elements.addElement(mie);
saverThread.enqueue(this);
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (MessagingException me) {
me.printStackTrace();
}
}
}
/**
* 巜掕偝傟偨儊僢僙乕僕偵懳墳偡傞僨乕僞僼傽僀儖傪嶍彍偡傞.
*
* @param msgs 嶍彍偡傞儊僢僙乕僕.
*/
public synchronized void remove(POP3Message msgs[]) {
Vector removeElements = new Vector();
for (int i = 0; i < msgs.length; ++i) {
MessageIndexElement elem = (MessageIndexElement) msgs[i].getInternalID();
elem.delete(dataDirectory);
removeElements.addElement(elem);
}
Enumeration e = removeElements.elements();
while (e.hasMoreElements()) {
elements.removeElement(e.nextElement());
}
saverThread.enqueue(this);
}
/**
* 偡傋偰偺儊僢僙乕僕僼傽僀儖傪嶍彍偡傞.
* 僨傿儗僋僩儕攝壓偺慡偰偺僼傽僀儖偑嶍彍偝傟傞丄
*
* @return 嶍彍偵惉岟偟偨応崌 true.
*/
public synchronized boolean removeAll() {
initElements();
String files[] = dataDirectory.list(
new FilenameFilter() {
public boolean accept(File dir, String name) {
File file = new File(dir, name);
if (file.isFile()) {
return true;
} else {
return false;
}
}
});
boolean result = true;
for (int i = 0; i < files.length; ++i) {
File file = new File(dataDirectory, files[i]);
if (! file.delete()) {
result = false;
}
}
return result;
}
/**
* 儊僢僙乕僕悢傪摼傞.
*
* @return 儊僢僙乕僕悢.
*/
public synchronized int getCount() {
return elements.size() - 1;
}
/**
* 僀儞僨僢僋僗僼傽僀儖傪曐懚偡傞.
*/
private synchronized void save() throws IOException {
if (elements.size() > 1 || indexFile.exists()) {
FileOutputStream fos = new FileOutputStream(indexFile);
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos, BUFFER_SIZE));
oos.writeObject(elements);
oos.close();
}
}
/**
* 慡僀儞僗僞儞僗偺僀儞僨僢僋僗傪曐懚偡傞.
*
* @exception java.io.IOException 僄儔乕偑敪惗偟偨応崌.
*/
static synchronized void saveAll() throws IOException {
if (saverThread != null) {
saverThread.saveAllIndexes();
}
}
/**
* 僀儞僨僢僋僗僼傽僀儖傪撉傒崬傓.
* 埲慜偺撪梕偼偡傋偰攋婞偝傟傞.
*
* @exception java.io.IOException 僄儔乕偑敪惗偟偨応崌.
*/
private synchronized void load() throws IOException {
initElements();
try {
FileInputStream fis = new FileInputStream(indexFile);
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis, BUFFER_SIZE));
elements = (Vector) ois.readObject();
ois.close();
} catch (FileNotFoundException fnfe) {
recoverIndex();
} catch (ClassNotFoundException cnfe) {
recoverIndex();
}
}
public synchronized void reload() throws IOException {
load();
}
/**
* 僀儞僨僢僋僗僼傽僀儖偑尒晅偐傜側偐偭偨応崌偺張棟傪峴偆.
*/
private void recoverIndex() throws IOException {
initElements();
if (dataDirectory.exists()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -