📄 messageheader.java
字号:
package mujmail;
/*
MujMail - Simple mail client for J2ME
Copyright (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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.util.Date;
import java.util.Vector;
import javax.microedition.lcdui.AlertType;
import mujmail.account.MailAccount;
import mujmail.util.Functions;
//#ifdef MUJMAIL_SEARCH
import mujmail.search.MessageSearchResult;
//#endif
/**
* Represents the header of the mail.
* It contains list of BodyParts (body of the mail + attachments) of given
* mail.
* It stores information from which account it was downloaded (accountID).
* The header is stored in rms database (recordID)
*/
public class MessageHeader {
/* ****************
* CONSTANTS *
******************/
private static final boolean DEBUG = false;
private static final String EMPTY_STRING = "";
// formats of message
public static final byte FRT_PLAIN = 0;
public static final byte FRT_MULTI = 1;
//body-fetch status
public static final byte NOT_READ = 0; //if was read by user, is set by mailForm
public static final byte READ = 1;
//if a header was stored on the device
public static final byte NOT_STORED = 0;
public static final byte STORED = 1; //if the header(not bodyparts) was stored once, no need to saved it once more in MailDb.saveHeaders()
//the size of bodyparts vector indicates whether each bodypart was stored
//because when a bodypart is stored to DB, bodyparts vector's size is increased
//body-sent status
public static final byte FAILED_TO_SEND = 0;
public static final byte TO_SEND = 1;
public static final byte SENT = 2;
public static final byte REPLIED = 4;
/** Message ID separator beetween Folder name and messageID obtained from server
* See RFC3501 5.1. // character This should not contain mailbox mane
*/
public static final char MSG_ID_SEPARATOR = '&';
/** String representation of {@link #MSG_ID_SEPARATOR} char */
public static final String MSG_ID_SEPARATOR_STR = new String( String.valueOf( MSG_ID_SEPARATOR ) );
/* *************************
* INSTANCE VARIABLES *
***************************/
//#ifdef MUJMAIL_SEARCH
/** Search result of the message. This item makes sense only when the message
has been searched and it was returned as the result of searching. */
private MessageSearchResult searchResult = MessageSearchResult.NO_MATCH;
//#endif
/** The record ID of the header in rms database */
private int recordID;
/** Original box where the message was before being deleted */
private char orgLocation;
//we must initiate from and recipients otherwise sort wont always work
private String from;
//we must initiate from and recipients otherwise sort wont always work
private String recipients;
private String subject;
/**
* Contains value of the boundary parameter of the Content-Type field.
* <p>
* Example:<br>
* if header contains line
* <pre>Content-Type: multipart/related; boundary=0016e659f8c86d2f8b0463bf768e</pre>
* than the <code>boundary</code> value is 0016e659f8c86d2f8b0463bf768e
* </p>
*/
private String boundary;
/** Unique primary key, that is by the way used to test existence of a mail in the mobile device; */
private String messageID;
/** Folder name where on server mail is stored */
private String imapFolder;
/**
* This field represents content of Message-ID field in e-mail message
* header. It used in threading algorithm to reference to parent message.
*
* While "Message-ID" field is optional in e-mail header (see
* <a href="http://tools.ietf.org/html/rfc5322#section-3.6.4">RFC 5322,
* section 3.6.4</a>), when not found in message header value from
* {@link #messageID} is used.
*/
private String threadingMessageID;
/** Account from which the mail was downloaded - must be given for every mail */
private String accountID;
byte messageFormat;
// TODO (Betlista): why aren't these statuses commented ?
byte readStatus;
byte DBStatus;
byte sendStatus;
/**
* Represents size of the email. The size is in bytes and could be little
* bit different from real received message size.
*/
private int size; //in Bytes
private long time;
boolean deleted = false;
boolean flagged = false;
// bodyParts vector is here to cache reading and displaying mail parts
private Vector bodyParts = new Vector();
// attachFileParts vector stores attachment file name, path and size
//Vector attachFileParts = new Vector();
// fields used in threading
/** flag that indicates whether the message is empty (have no body) */
// TODO: that is not true: the message has no body if message.getBodyPartCount() == 0
// this is some threading field!!
private boolean isEmpty = true;
/**
* Represents thread parent - all messages in thread have same parent
* parent message can be empty (see {@link #isEmpty})
* parent ID can be empty, but it's not null, it's ""
*
* Parent ID is stored also in {@link #parentIDs parentIDs vector}.
* Parent ID could be changed when threading of messages is performed.
*/
private String parentID = null;
/**
* Represents value of <code>In-Reply-To</code> header from e-mail header.
* There is (just small) probability that there is no messageID in this header.
*/
private String replyTo = null;
/**
* Represents path to root message.
* It can be empty (Vector with 0 size).
* It is never null, to prevent comparing with null again and again.
*/
private Vector/*<String>*/ parentIDs = null;
/** The box to which this message belongs */
private final PersistentBox box;
/* *******************
* CONSTRUCTORS *
*********************/
public MessageHeader(PersistentBox box) {
this.box = box;
orgLocation = 'X';
from = "+sender@server.com+";
recipients = "+recipient@server.com+";
subject = EMPTY_STRING;
accountID = "mujmail@cia.gov";
messageFormat = FRT_PLAIN;
readStatus = NOT_READ;
DBStatus = NOT_STORED;
sendStatus = TO_SEND;
parentIDs = new Vector();
parentID = EMPTY_STRING;
threadingMessageID = Long.toString( System.currentTimeMillis(), 35 ) + "@mujmail.org";
isEmpty = false;
imapFolder = EMPTY_STRING;
}
/**
* Makes a copy of given message header. Does not copy bodyparts.
* @param box
* @param copy
*/
public MessageHeader(PersistentBox box, MessageHeader copy) {
this(box);
orgLocation = copy.orgLocation;
recordID = copy.recordID;
from = copy.from;
recipients = copy.recipients;
subject = copy.subject;
boundary = copy.boundary;
messageID = copy.messageID;
imapFolder = copy.imapFolder;
accountID = copy.accountID;
messageFormat = copy.messageFormat;
readStatus = copy.readStatus;
DBStatus = copy.DBStatus;
sendStatus = copy.sendStatus;
size = copy.size;
time = copy.time;
deleted = copy.deleted;
threadingMessageID = copy.threadingMessageID;
parentID = copy.parentID;
Vector copyParentIDs = copy.parentIDs;
if ( copyParentIDs != null ) {
final int size = copyParentIDs.size();
parentIDs = new Vector( size );
for ( int i = 0; i < size; ++i) {
parentIDs.addElement( copyParentIDs.elementAt( i ) );
}
}
}
/*
* call this when sending a new mail
* practically we don't need to create an instance of MessageHeader to send a simple mail, just use strings
* but this constructor will be needed when forwarding or send a multipart mail.
* ID must be generated randomly for each header.
* So we create one extra MessageHeader instance...
*/
public MessageHeader(PersistentBox box, String frm, String rcps, String sbj, String ID, long tm) {
this(box);
from = frm;
recipients = rcps;
subject = sbj;
messageID = ID;
time = tm;
}
/* **************************
* GETTERS AND SETTERS *
****************************/
/**
* Gets the box to which this message belongs.
* @return
*/
public PersistentBox getBox() {
return box;
}
public MailDB getMailDB() {
return box.getMailDB();
}
/**
* Returns true if this message is special threading message.
* @return
*/
public boolean isEmpty() {
return isEmpty;
}
/**
*
* @param isEmpty true if this message is special threading message
*/
public void setEmpty(boolean isEmpty) {
this.isEmpty = isEmpty;
}
public String getParentID() {
return parentID;
}
public void setParentID(String parentID) {
if (parentID == null) {
this.parentID = EMPTY_STRING;
} else {
if ( parentID.equals( this.threadingMessageID ) ) {
System.out.println( "ERROR MessageHeader.setParentID(String) - trying to set parentID same as the threadingMessageID" );
if (DEBUG) {
System.out.println( "DEBUG MessageHeader.setParentID(String) - header: " + this.toString() );
throw new IllegalArgumentException();
}
} else {
this.parentID = parentID;
}
}
}
public String getReplyTo() {
return replyTo;
}
public void setReplyTo(String replyTo) {
this.replyTo = replyTo;
}
public Vector/*<String>*/ getParentIDs() {
return parentIDs;
}
public void setParentIDs(Vector parentIDs) {
if ( parentIDs == null ) {
this.parentIDs = new Vector(0);
} else {
this.parentIDs = parentIDs;
}
}
public int getRecordID() {
return recordID;
}
public void setRecordID(int recordID) {
this.recordID = recordID;
}
public void setRecipients(String recipients) {
this.recipients = recipients;
}
public void setOrgLocation(char orgLocation) {
this.orgLocation = orgLocation;
}
public char getOrgLocation() {
return orgLocation;
}
/**
* Call if this message failed to send.
*/
public void setFailedToSend() {
sendStatus = FAILED_TO_SEND;
}
/**
* Call if this message was successfully sent.
*/
public void setSent() {
sendStatus = SENT;
}
/**
* Returns true if this message was already read.
* @return true if this message was already read.
*/
public boolean wasRead() {
return readStatus == READ;
}
/**
* Marks this message as plain message.
*/
public void markAsPlain() {
messageFormat = FRT_PLAIN;
}
/**
* Marks this message as multipart message.
*/
public void markAsMultipart() {
messageFormat = FRT_MULTI;
}
/**
* Marks this message as read.
*/
public void markAsRead() {
readStatus = READ;
}
/**
* Adds recipient to the message.
* @param recipient the recipient to be added.
*/
public void addRecipient(String recipient) {
if (recipients.startsWith("+")) //has default value
{
recipients = recipient + " *";
} else {
recipients += recipient + " *";
}
}
public String toString() {
return super.toString() + "/n Number of bodyparts = " + getBodyPartCount();
}
/**
* Ensures whether there is a recipient specified. If not, adds default
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -