📄 maildb.java
字号:
final Vector storedMessages = new Vector(recordsNumber); while (enumeration.hasNextElement()) { try { id = enumeration.nextRecordId(); sizeOfRecord = headerRS.getRecordSize(id); if (sizeOfRecord > data.length) { data = new byte[sizeOfRecord + 100]; inputStream = new DataInputStream(new ByteArrayInputStream(data)); } headerRS.getRecord(id, data, 0); inputStream.reset(); //read from the beginning MessageHeader header = new MessageHeader(progress.actionInvoker); //create a new header // TODO ALF //read the important information from the stream header.setRecordID(id); header.setOrgLocation(inputStream.readChar()); header.setFrom(inputStream.readUTF()); header.setRecipients(inputStream.readUTF()); header.setSubject(inputStream.readUTF()); header.setBoundary(inputStream.readUTF()); header.setMessageID(inputStream.readUTF()); header.setIMAPFolder(inputStream.readUTF()); header.setAccountID(inputStream.readUTF()); header.messageFormat = inputStream.readByte(); header.readStatus = inputStream.readByte(); header.flagged = inputStream.readBoolean(); header.DBStatus = inputStream.readByte(); header.sendStatus = inputStream.readByte(); header.setSize(inputStream.readInt()); header.setTime(inputStream.readLong()); // fields for threading header.setThreadingMessageID( loadNullable( inputStream.readUTF() ) ); header.setParentID( loadNullable( inputStream.readUTF() ) ); int parents = inputStream.readInt(); Vector parentIDs = new Vector(); for (int i = 0; i < parents; ++i) { parentIDs.addElement(inputStream.readUTF()); } header.setParentIDs(parentIDs); bodyPartsCount = inputStream.readByte(); //now create a new bodypart and read its information for (byte k = 0; k < bodyPartsCount; k++) { BodyPart bp = new BodyPart(header); bp.loadBodyPart(inputStream); header.addBodyPart(bp); } //change the counter of unread mails of the Inbox and use boxes if (header.readStatus == MessageHeader.NOT_READ) { MujMail.mujmail.getMailDBManager().changeUnreadMails(this, 1); } storedMessages.addElement(header); //add the header to the appropriate box progress.incActual(1); if (progress.stopped()) { break; } } catch (Exception exp) { //usually its EOFException exp.printStackTrace(); //try another header } } if (Algorithm.DEBUG) System.out.println( "DEBUG MailDB.loadHeaders(MailDBTask) - box name: " + progress.actionInvoker.getName() ); progress.actionInvoker.setStorage(Algorithm.getAlgorithm().invoke(storedMessages)); if (inputStream != null) { inputStream.close(); } data = null; } } catch (Exception ex) { ex.printStackTrace(); throw new MyException(MyException.DB_CANNOT_LOAD_HEADERS); } catch (Error er) { er.printStackTrace(); throw new MyException(MyException.SYS_OUT_OF_MEMORY); } finally { Functions.closeRecordStore(headerRS); } if (DEBUG) { System.out.println("DEBUG MailDB.loadHeaders() - end - " + dbName); } } private void _deleteMail(MailDBTask progress, MessageHeader header) throws MyException { for (byte j = (byte) (header.getBodyPartCount() - 1); j >= 0; --j) { BodyPart bp = (BodyPart) header.getBodyPart(j); bp.getStorage().deleteContent(); } RecordStore headerRS = null; try { headerRS = RecordStore.openRecordStore(dbName + "_H", true); } catch (Exception ex) { throw new MyException(0); } if (headerRS != null) { try { headerRS.deleteRecord(header.getRecordID()); } catch (Exception ex) { progress.actionInvoker.report("+" + Lang.get(Lang.ALRT_DELETING) + header.getSubject() + Lang.get(Lang.FAILED) + ": " + ex, SOURCE_FILE); throw new MyException(0); } } Functions.closeRecordStore(headerRS); } //batch mails deleting. private void _deleteMails(MailDBTask progress) throws MyException { progress.actionInvoker.report(Lang.get(Lang.ALRT_DELETING) + progress.actionInvoker.getName(), SOURCE_FILE); //lock the container as were gonna to modify it, so owningBox.repaint() and other things will not crash final IStorage storage = progress.actionInvoker.storage; synchronized (storage) { //this silly sorting prevents DB corruption as we markAsDeleted headers with higher record id first //it seems like emulator's bad implementation of RMS, not sure if it happens to normal phones as well // TODO (Betlista) - uncomment: the code bellow //Functions.sort(owningBox.storage, Functions.SRT_ORDER_INC, Functions.SRT_HDR_RECORD_ID); final int storageSize = storage.getSize(); Vector/*<MessageHeader>*/ toDel = new Vector/*<MessageHeader>*/(); // Collect emails marked as delete for (int i = 0; i < storageSize; ++i) { MessageHeader header = (MessageHeader) storage.getMessageAt(i); if (header.deleted) { toDel.addElement(header); } } // Remove emails marked for deletion for(Enumeration e = toDel.elements(); e.hasMoreElements();) { MessageHeader mh = (MessageHeader)e.nextElement(); // move to trash MujMail.mujmail.getTrash().storeToTrash(mh, Trash.TrashModes.CONDITIONALLY_MOVE_TO_TRASH); // remove mail from database _deleteMail(progress, mh); // remove mail from storage storage.removeMessage(mh); --progress.actionInvoker.deleted; } progress.actionInvoker.resort();// we sorted by recordID before the iteration MujMail.mujmail.getTrash().resort(); } } private void saveHeader(RecordStore headerRS, final MessageHeader header) throws RecordStoreNotOpenException, RecordStoreException, IOException, Exception { ByteArrayOutputStream byteStream; DataOutputStream outputStream; byteStream = new ByteArrayOutputStream(); outputStream = new DataOutputStream(byteStream); //if it was stored then this is update procedure boolean update = header.DBStatus == MessageHeader.STORED; if (header.getOrgLocation() == 'X') { header.setOrgLocation(dbName.charAt(0)); } outputStream.writeChar(header.getOrgLocation()); outputStream.writeUTF(header.getFrom()); outputStream.writeUTF(header.getRecipients()); outputStream.writeUTF(header.getSubject()); if (header.getBoundary() == null) { header.setBoundary(header.getMessageID()); } outputStream.writeUTF(header.getBoundary()); outputStream.writeUTF(header.getMessageID()); outputStream.writeUTF(header.getIMAPFolder()); outputStream.writeUTF(header.getAccountID()); outputStream.writeByte(header.messageFormat); outputStream.writeByte(header.readStatus); outputStream.writeBoolean(header.flagged); header.DBStatus = MessageHeader.STORED; outputStream.writeByte(header.DBStatus); outputStream.writeByte(header.sendStatus); outputStream.writeInt(header.getSize()); outputStream.writeLong(header.getTime()); // fields for threading outputStream.writeUTF(saveNullable(header.getThreadingMessageID())); outputStream.writeUTF(saveNullable(header.getParentID())); Vector parentIDs = header.getParentIDs(); /*<String>*/ int parentsCount = parentIDs.size(); outputStream.writeInt(parentsCount); for (int i = 0; i < parentsCount; ++i) { // this should not be null outputStream.writeUTF(parentIDs.elementAt(i).toString()); } // save also all bodypart headers byte size = header.getBodyPartCount(); if (DEBUG) System.out.println("DEBUG - MailDB.saveHeader() - number of bodyparts " + size); outputStream.writeByte(size); for (byte j = 0; j < size; j++) { header.getBodyPart(j).saveBodyPart(outputStream); } outputStream.flush(); /*this code doesnt always work, seems like bad implementation of RMS if (update) headerRS.setRecord(header.recordID, byteStream.toByteArray(), 0, byteStream.size() ); else header.recordID = headerRS.addRecord( byteStream.toByteArray(), 0, byteStream.size() ); */ /*this seems working most of time:**/ int oldID = header.getRecordID(); header.setRecordID(headerRS.addRecord(byteStream.toByteArray(), 0, byteStream.size())); if (update) { try { headerRS.deleteRecord(oldID); } catch (Exception ignored) { } } outputStream.close(); byteStream.close(); } /** * Performs stoppable actions. */ private class MailDBTask extends StoppableBackgroundTask { /** The box which invoke action. * Note: Used for error reporting in background tasks. */ private PersistentBox actionInvoker; /** Specific action to do */ private byte runMode; /** Select mail to delete (in case single mail delete) */ private MessageHeader messageHeaderToDelete; public MailDBTask(PersistentBox actionInvoker, byte runMode) { super("Database task " + actionInvoker.getDBFileName() + " MailDBTask " + runMode); this.actionInvoker = actionInvoker; this.runMode = runMode; } void setMessageHeaderToDelete(MessageHeader messageHeaderToDelete) { this.messageHeaderToDelete = messageHeaderToDelete; } public void doWork() { if (MailDB.DEBUG) System.out.println("Starting MailDBTask"); busy = true; switch (runMode) { case RUNMODE_LOAD: try { loadHeaders(this); if (MailDB.DEBUG) System.out.println("MailDBTask.doWork - loadHeaders finnished"); actionInvoker.report(Lang.get(Lang.ALRT_LOADING) + actionInvoker.getName() + " " + Lang.get(Lang.SUCCESS), SOURCE_FILE); } catch (MyException ex) { ex.printStackTrace(); actionInvoker.report(Lang.get(Lang.ALRT_LOADING) + actionInvoker.getName() + " " + Lang.get(Lang.FAILED) + ": " + ex.getDetails(), SOURCE_FILE); } MujMail.mujmail.getMailDBManager().loadedDB(MailDB.this); if (MailDB.DEBUG) System.out.println("MailDBTask.doWork - loadHeaders after loadedDB"); break; case RUNMODE_DELETE_ALL_MAILS: if (MailDB.DEBUG) System.out.println("DEBUG MailDBTask.doWork() - starting deleting all mails"); try { _deleteMails(this); if (MailDB.DEBUG) System.out.println("DEBUG MailDBTask.doWork() - end deleting all mails"); actionInvoker.report(Lang.get(Lang.ALRT_DELETING) + actionInvoker.getName() + " " + Lang.get(Lang.SUCCESS), SOURCE_FILE); if (MailDB.DEBUG) System.out.println("DEBUG MailDBTask.doWork() - success reported"); } catch (MyException ex) { actionInvoker.report(Lang.get(Lang.ALRT_DELETING) + actionInvoker.getName() + " " + Lang.get(Lang.FAILED) + ": " + ex.getDetails(), SOURCE_FILE); } break; case RUNMODE_DELETE_MAIL: try { System.out.println("MailDB.doWork - starting to delete mail"); _deleteMail(this, messageHeaderToDelete); System.out.println("MailDB.doWork - mail succesfully deleted"); actionInvoker.report(Lang.get(Lang.ALRT_DELETING) + actionInvoker.getName() + " " + Lang.get(Lang.SUCCESS), SOURCE_FILE); } catch (MyException ex) { actionInvoker.report(Lang.get(Lang.ALRT_DELETING) + actionInvoker.getName() + " " + Lang.get(Lang.FAILED) + ": " + ex.getDetails(), SOURCE_FILE); } break; } synchronized(notifier) { busy = false; notifier.notifyAll(); } //dbLoadingTask = null; // Loading task ended actionInvoker.repaint(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -