📄 maildb.java
字号:
/*MujMail - Simple mail client for J2MECopyright (C) 2006 Nguyen Son Tung <n.sontung@gmail.com>Copyright (C) 2006 Martin Stefan <martin.stefan@centrum.cz>Copyright (C) 2008 David Hauzar <david.hauzar.mujmail@gmail.com>This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package mujmail;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.util.Enumeration;import java.util.Vector;import javax.microedition.rms.InvalidRecordIDException;import javax.microedition.rms.RecordEnumeration;import javax.microedition.rms.RecordStore;import javax.microedition.rms.RecordStoreException;import javax.microedition.rms.RecordStoreNotOpenException;import mujmail.tasks.StoppableBackgroundTask;import mujmail.threading.Algorithm;import mujmail.ui.OKCancelDialog;import mujmail.util.Callback;import mujmail.util.Functions;import mujmail.util.StartupModes;/** * Provides functions for storing mail headers and low level functions * for storing fragments of body parts of mails used in class {@link RMSStorage}. */public class MailDB { /** True if mail header are actually saved. */ //private boolean savingHeader = false; /** The name of this source file */ private static final String SOURCE_FILE = "MailDB"; /** Flag signals if we want to print debug prints */ private static final boolean DEBUG = false; /// Debugging output for this file /** The number of headers to delete from headers database if database is full. */ private static final int NUM_HEADERS_TO_DELETE_IF_DB_FULL = 5; /** The size of free space in header database when start to delete headers or notice user that the space is left. */ private static final int FREE_SPACE_IN_HEADER_DB_WHEN_DELETE_HEADERS = 3000; private final static byte RUNMODE_LOAD = 1; private final static byte RUNMODE_DELETE_ALL_MAILS = 2; private final static byte RUNMODE_DELETE_MAIL = 3; public final static String safeModeDBFile = "safemodeStore"; //Vector hdrRefer; // TODO (Betlista): I not sure if it is safe to store reference to storage // for example: when there is new e-mail all mails have to be threaded // and this operation recreates new storage (creates new instance), so this // is the reason why it should NOT to store reference /** Database file name where mail are stored */ private String dbName; /** The dbLoadingTask that loads the database. */ private StoppableBackgroundTask dbLoadingTask = null; private boolean busy; /// Marks if running any dbLoadingTask (loading or deleteing, adding) or all dbLoadingTask had been finnished private Object notifier = new Object(); /// Object on which wait fo beeing notify public MailDB(String dbName) { busy = true; this.dbName = dbName; } /** * Loads headers in this database in new thread. * @param reportBox box which db become to */ public void loadDB(PersistentBox reportBox) { if (DEBUG) { System.out.println("MailDB.loadDB - " + dbName); } // TODO: set max priority to this dbLoadingTask busy = true; dbLoadingTask = new MailDBTask(reportBox, RUNMODE_LOAD); dbLoadingTask.disableDisplayingProgress(); dbLoadingTask.disableDisplayingUserActionRunnerUI(); dbLoadingTask.start(reportBox); } public StoppableBackgroundTask getDBLoadingTask() { return dbLoadingTask; } /** * Delete all mails marked as to markAsDeleted. * @param reportBox box which db become to */ public void deleteMails(PersistentBox reportBox) { // TODO: set max priority to this dbLoadingTask busy = true; StoppableBackgroundTask task = new MailDBTask(reportBox, RUNMODE_DELETE_ALL_MAILS); task.disableDisplayingProgress(); task.start(reportBox); } /** * Deletes mail from database. Does not update the vector where the mail * is stored in TheBox. * @param header */ public void deleteMail(MessageHeader header, PersistentBox reportBox) { if (this != header.getMailDB()) { throw new RuntimeException("Called on bad database"); } // TODO: set max priority to this dbLoadingTask MailDBTask task = new MailDBTask(reportBox, RUNMODE_DELETE_MAIL); task.setMessageHeaderToDelete(header); task.disableDisplayingProgress(); task.start(reportBox); //task.doWork(); } public String getDBName() { return dbName; } public boolean isBusy() { return busy; } /** @return Block and wait until any of running tasks end. * Returns immediatelly if no dbLoadingTask running. */ public void waitForTaskEnd() { if (DEBUG) { System.out.println("DEBUG AccountSettings.waitForAccountsLoading .. in"); } try { synchronized(notifier) { if (!busy) return; notifier.wait(); } } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); } if (DEBUG) { System.out.println("DEBUG AccountSettings.waitForAccountsLoading .. out"); } } /** * This method clears all records in the database. * By default removes all message bodies. * @param headers If set remove message headers too. */ public void clearDb(boolean headers) throws MyException { boolean exception = false; // Mark if exception raise // Body db { try { RecordStore.deleteRecordStore(dbName); } catch (Exception ex) { exception = true; if (DEBUG) { System.out.println("DEBUG MailDB.clearDB - removing mail body problem from DB: " + dbName); System.out.println(ex); ex.printStackTrace(); } } } // Headers db if (headers) { try { RecordStore.deleteRecordStore(dbName + "_H"); } catch (Exception ex) { exception = true; if (DEBUG) { System.out.println("DEBUG MailDB.clearDB - removing mail headers db problem DB: " + dbName + "_H"); System.out.println(ex); ex.printStackTrace(); } } } // throw exception if problem if (exception) { throw new MyException(MyException.DB_CANNOT_CLEAR); } } /** * This method saves a bodypart of a message as a new record in a different RecordStore which name is determined TheBox.name * @param body - a String that is supposed to be save. Whole bodypart is stored as one String. The other information * about the bodypart are hold in a <code>Vector</code> and stored separatly. * Then we return an index which will be stored in bodyPart.recordID. * Synchronization is ensured by the rms system. * * @see RMSStorage */ int saveFragmentBodypartContent(String body, boolean safeMode) throws MyException { if (DEBUG) { System.out.println("MailDB.saveBodypartContent: " + body); } int index = -1; if (body.length() == 0) { body = "<no content>"; } //we must do this, because sending a mail, without a body is supported //we will try to minimize using DB by recycling common record store safeModeDBFile for mails if (DEBUG) { System.out.println("Saving body part content"); } RecordStore bodyRS = Functions.openRecordStore(safeMode?safeModeDBFile:dbName, true); try { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); DataOutputStream outputStream = new DataOutputStream(byteStream); outputStream.writeUTF(body); outputStream.flush(); index = bodyRS.addRecord(byteStream.toByteArray(), 0, byteStream.size()); outputStream.close(); byteStream.close(); } catch (Exception ex) { throw new MyException(MyException.DB_CANNOT_SAVE_BODY); } finally { Functions.closeRecordStore(bodyRS); } if (DEBUG) { System.out.println("Body part content saved"); } return index; } /** * this method is for saving binary data * @param body * @param safeMode * @return * @throws MyException * * @see RMSStorage */ int saveFragmentOfBodypartContent(byte[] body, boolean safeMode) throws MyException { int index = -1; if (DEBUG) { System.out.println("Saving body part content raw"); } RecordStore bodyRS = Functions.openRecordStore( safeMode?safeModeDBFile:dbName, true); try { index = bodyRS.addRecord(body, 0, body.length); } catch (Exception ex) { throw new MyException(MyException.DB_CANNOT_SAVE_BODY); } finally { Functions.closeRecordStore(bodyRS); } if (DEBUG) { System.out.println("Body part content raw saved"); } return index; } /** * By this method we get the real content of a body part in byte[]. Can be used by a class that displays mails * @param dbFileName * @param recordID * @return * @throws MyException * * @see RMSStorage */ static byte[] loadFragmentBodypartContentRaw(String dbFileName, int recordID) throws MyException { byte[] body = null; if (DEBUG) { System.out.println("Loading body part content"); } RecordStore bodyRS = Functions.openRecordStore(dbFileName, true); try { body = bodyRS.getRecord(recordID); } catch (Exception ex) { throw new MyException(MyException.DB_CANNOT_LOAD_BODY); } finally { Functions.closeRecordStore(bodyRS); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -