?? 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.BufferedReader;
import java.io.ByteArrayInputStream;
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.InputStreamReader;
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();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -