📄 inprotocol.java
字号:
/** * Parse the line to get boundary parameter value and it is set to message * header. * * @param header the header that boundary is set for * @param line the input line with boundary * @param lower the lower case version of line * @see #getBoundaryParamValue(int, String) */ private void setBoundary( final MessageHeader header, final int index, final String line, final String lower ) { if (DEBUG) System.out.println("setBoundary(line='" + line + "', lower='" + lower + "')"); final String boundaryValue = getBoundaryParamValue( index, line ); header.setBoundary( "--" + boundaryValue ); } /** * Determines whether given mail should be redownloaded. * * @param bp the body part which has been yet downloaded * @param header the header of original message * @return */ private boolean shouldBeRedownloaded(BodyPart bp, MessageHeader header) { return true; // TODO: (David) before redownloading we don't know size of bodypart that will // be downloaded so bp.getSize() is always zero so it makes no sence to // compare it with old one. // That means want to always redownload the message. // Get rid of this method?// if (header.isPlain()) {//// // redownload the e-mail, if newly downloaded body part is better, that// // means it's bigger than the old one or if the e-mail is not// // downloaded yet (header.getBodyPartCount() == 0)// if ( (header.getBodyPartCount() == 0 || bp.getSize() > header.getBpSize((byte) 0)) ) {// return true;// }//// return false;// } else {// // if body part is not in e-mail yet or body part is better// // (that means it's bigger than the old one)// if ( (!isInMail(header, bp) || isBigger(header, bp) ) ) {// return true;// }//// return false;// } } /** * Parses data in the body of the mail: this means data after the header * of the mail. * @param header * @param progress used to display progress and stop the action * @throws MyException */ protected void parseBody(MessageHeader header, StoppableProgress progress) throws MyException { // TODO: there can occur OutOFMemoryError when reading line from the // connection. Catch such error, flush buffers, unGetLine and read // the line again. if (DEBUG) { System.out.println("DEBUG InProtocol.parseBody - before execution"); } try { //if plain mail, then its just text or HTML: fetch it if (header.isPlain()) { parseBodyOfPlainMessage(header, progress); } else { //multipart mail: fetch all body parts that we want to fetch parseBodyOfMultipartMessage(header, progress); } } catch (Throwable err) { // delete the content of last downloaded bodypart err.printStackTrace(); handleNotSuccesfullyDownloaded(actuallyParsedBodyPart); if (runMode == CONVERT_BODY) { actuallyParsedBodyPart.switchToNotConvertedContent(); } throw new MyException(0, err); } System.out.println("Header = " + header); } //this function clears partially downloaded mails //if something went wrong and other previous bodyparts were stored to the DB //but those bodyparts will never be accessible, because we could not update headers info about them into DB. //thus those unreacheable bodyparts will cause a DB leak. protected void clear(MessageHeader header) { for (byte i = (byte) (header.getBodyPartCount() - 1); i >= 0; --i) { try { header.getBodyPart(i).getStorage().deleteContent(); } catch (Exception exp) { exp.printStackTrace(); } } //also mark the mail as not downloaded(no bodyparts) so next time it could be downloaded header.deleteAllBodyParts(); } //clears and wakes up MailForm (or anything having actheader as semaphore) protected synchronized void fixAndNotify() { if (DEBUG) { System.out.println("DEBUG InProtocol.fixAndNotify - before execution"); } if (actHeader == null) { return; } try { actHeader.saveHeader(); //box.getMailDB().saveHeader(actHeader); } catch (Exception any) { clear(actHeader); } if (DEBUG) { System.out.println("DEBUG InProtocol.fixAndNotify - before actHeader"); } synchronized (actHeader) { actHeader.notify(); actHeader = null; } if (DEBUG) { System.out.println("DEBUG InProtocol.fixAndNotify - after actHeader"); } } //solves an error raised during common function protected void resolveExceptions(String errorDetails, String sourceFile) { if (getTargetBox() != null && getTargetBox().isSyncRunning()) { ((InBox)getTargetBox()).synchronizationError(); } //something's gone wrong, now we have to stop sync if (runMode == InProtocol.RETRIEVE_BODY || runMode == InProtocol.REDOWNLOAD_BODY) { fixAndNotify(); } getReportBox().report(errorDetails, sourceFile + " -> " + SOURCE_FILE); } /** * Displays the alert if fetching body failed. */ private void displayAlertIfFetchingBodyFailed(BodyPart bp, Progress progress) { progress.setTitle(Lang.get(Lang.ALRT_SAVING) + bp.getMessageHeader().getSubject() + "/" + bp.getHeader().getName() + " " + Lang.get(Lang.FAILED) + " " + Lang.get(Lang.ALRT_SYS_LOW_MEMORY) + " / " + Lang.get(Lang.ALRT_SYS_NO_DBSPACE)); } private void handleNotSuccesfullyDownloaded(BodyPart bp) { if (MessageHeader.canBePartiallySaved(bp)) { try { bp.getStorage().flushBuffer(); } catch (Exception ex) { ex.printStackTrace(); } bp.setBodyState(BodyPart.BS_PARTIAL); } else { System.out.println("Cannot be partially saved"); if (bp.getBodyState() != BodyPart.BS_EMPTY) bp.getStorage().deleteContent(); bp.setBodyState(BodyPart.BS_EMPTY); } System.out.println("After handle not succesfully"); } //check whether a bodypart is in the header private boolean isInMail(MessageHeader header, BodyPart bp) { for (byte i = (byte) (header.getBodyPartCount() - 1); i >= 0; --i) { if (header.getBpOriginalOrder(i) == bp.getOrder()) { return true; } } return false; } //checks whether the bodypart bp is bigger than the same bodypart stored in header private boolean isBigger(MessageHeader header, BodyPart bp) { for (byte i = (byte) (header.getBodyPartCount() - 1); i >= 0; --i) { if (header.getBpOriginalOrder(i) == bp.getOrder() && header.getBpSize(i) < bp.getSize() ) { return true; } } return false; } public boolean isImap() { return false; } /** @return box used for reporting errors */ protected TheBox getReportBox() { return reportBox; } /** @return InBox where mail changes (adding, removing) take place */ protected InBox getTargetBox() { return targetBox; } /** * Do the work of closing the connection. * @param task TODO: add description * @param waitForReply true if it should be waited for reply from the server * after sending closing command. */ protected abstract void _close(BackgroundTask task, boolean waitForReply); /** * TODO (Betlista): add description * @param task TODO: add description */ protected void _close(BackgroundTask task) { _close(task, true); } /** * closing connection when forcedDisc is true. */ protected void closeForceDist() { //setAlert(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail()); inProtocolTask.updateProgress(2, 1); inProtocolTask.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail()); _close(inProtocolTask); //setAlert(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail() + Lang.get(Lang.SUCCESS)); inProtocolTask.updateProgress(2, 2); inProtocolTask.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail() + Lang.get(Lang.SUCCESS)); forcedDisc = false; decThreadGlobal(); //getReportBox().repaint(); } private void actionAfterTasksCompleted() { decThread(); decThreadGlobal(); unlock(); synchronized (getTargetBox()) { //if im the last headerRetrieving thread, i should resort the box if (getTargetBox().isNeedResort() && !InProtocol.isBusyGlobal()) { incThreadGlobal(); //this will make thebox trigger the progress bar getTargetBox().resort(); getTargetBox().setNeedResort(false); getTargetBox().setCurFirstUnread(); decThreadGlobal(); } //if its servers sync notify the box to completed the sync process if (getTargetBox().isSyncRunning()) { getTargetBox().serversSync(inProtocolTask); } } //getReportBox().repaint(); } protected static class InProtocolTask extends StoppableBackgroundTask { private final InProtocol inProtocol; public InProtocolTask(InProtocol inProtocol, String label) { super(label); this.inProtocol = inProtocol; } public void doWork() { inProtocol.doWork(); } } /** * Returns true if getting body part should be stopped. * @param progress the progress that indicates whether getting should be * stopped * @param bodyPartSize the size of already downloaded bodypart. * @param linesCount the number of lines that were already downloaded. * @return true if downladng body part should be stopped. */ private boolean stopDownloadingBodyPart(StoppableProgress progress, long bodyPartSize, int linesCount) { return progress.stopped() || bodyPartSize > Settings.getMaxSizeOfBodypart() || (Settings.maxLinesRetrieve != -1 && linesCount > Settings.maxLinesRetrieve); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -