IMAP: convert Exchange message uid to long to create persistent IMAP uids
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@311 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
79b90c62d9
commit
81f88a5d18
|
@ -7,14 +7,15 @@ import org.apache.commons.httpclient.auth.AuthenticationException;
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import org.apache.commons.httpclient.methods.PutMethod;
|
import org.apache.commons.httpclient.methods.PutMethod;
|
||||||
|
import org.apache.commons.httpclient.util.Base64;
|
||||||
import org.apache.commons.httpclient.util.URIUtil;
|
import org.apache.commons.httpclient.util.URIUtil;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.webdav.lib.Property;
|
import org.apache.webdav.lib.Property;
|
||||||
import org.apache.webdav.lib.ResponseEntity;
|
import org.apache.webdav.lib.ResponseEntity;
|
||||||
import org.apache.webdav.lib.WebdavResource;
|
import org.apache.webdav.lib.WebdavResource;
|
||||||
|
import org.apache.webdav.lib.methods.MoveMethod;
|
||||||
import org.apache.webdav.lib.methods.PropPatchMethod;
|
import org.apache.webdav.lib.methods.PropPatchMethod;
|
||||||
import org.apache.webdav.lib.methods.SearchMethod;
|
import org.apache.webdav.lib.methods.SearchMethod;
|
||||||
import org.apache.webdav.lib.methods.MoveMethod;
|
|
||||||
import org.htmlcleaner.CommentToken;
|
import org.htmlcleaner.CommentToken;
|
||||||
import org.htmlcleaner.HtmlCleaner;
|
import org.htmlcleaner.HtmlCleaner;
|
||||||
import org.htmlcleaner.TagNode;
|
import org.htmlcleaner.TagNode;
|
||||||
|
@ -452,6 +453,7 @@ public class ExchangeSession {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace invalid url chars
|
* Replace invalid url chars
|
||||||
|
*
|
||||||
* @param subject
|
* @param subject
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -542,6 +544,9 @@ public class ExchangeSession {
|
||||||
message.read = "1".equals(prop.getPropertyAsString());
|
message.read = "1".equals(prop.getPropertyAsString());
|
||||||
} else if ("message-id".equals(prop.getLocalName())) {
|
} else if ("message-id".equals(prop.getLocalName())) {
|
||||||
message.messageId = prop.getPropertyAsString();
|
message.messageId = prop.getPropertyAsString();
|
||||||
|
if (message.messageId.startsWith("<") && message.messageId.endsWith(">")) {
|
||||||
|
message.messageId = message.messageId.substring(1, message.messageId.length()-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,27 +570,27 @@ public class ExchangeSession {
|
||||||
|
|
||||||
public void updateMessage(Message message, Map<String, String> properties) throws IOException {
|
public void updateMessage(Message message, Map<String, String> properties) throws IOException {
|
||||||
PropPatchMethod patchMethod = new PropPatchMethod(URIUtil.encodePathQuery(message.messageUrl));
|
PropPatchMethod patchMethod = new PropPatchMethod(URIUtil.encodePathQuery(message.messageUrl));
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<String,String> entry:properties.entrySet()) {
|
for (Map.Entry<String, String> entry : properties.entrySet()) {
|
||||||
if ("read".equals(entry.getKey())) {
|
if ("read".equals(entry.getKey())) {
|
||||||
patchMethod.addPropertyToSet("read", entry.getValue(), "e", "urn:schemas:httpmail:");
|
patchMethod.addPropertyToSet("read", entry.getValue(), "e", "urn:schemas:httpmail:");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
patchMethod.setDebug(4);
|
|
||||||
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
|
||||||
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
|
||||||
throw new IOException("Unable to update message properties");
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
patchMethod.releaseConnection();
|
|
||||||
}
|
}
|
||||||
|
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
||||||
|
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
||||||
|
throw new IOException("Unable to update message properties");
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
patchMethod.releaseConnection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public List<Message> getAllMessages(String folderName) throws IOException {
|
|
||||||
|
public MessageList getAllMessages(String folderName) throws IOException {
|
||||||
String folderUrl = getFolderPath(folderName);
|
String folderUrl = getFolderPath(folderName);
|
||||||
List<Message> messages = new ArrayList<Message>();
|
MessageList messages = new MessageList();
|
||||||
String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
|
String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
|
||||||
" ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\""+
|
" ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\"" +
|
||||||
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
|
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
|
||||||
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" +
|
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" +
|
||||||
" ORDER BY \"urn:schemas:httpmail:date\" ASC";
|
" ORDER BY \"urn:schemas:httpmail:date\" ASC";
|
||||||
|
@ -597,6 +602,7 @@ public class ExchangeSession {
|
||||||
Message message = buildMessage(entity);
|
Message message = buildMessage(entity);
|
||||||
messages.add(message);
|
messages.add(message);
|
||||||
}
|
}
|
||||||
|
Collections.sort(messages);
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +612,7 @@ public class ExchangeSession {
|
||||||
String searchRequest = "Select \"DAV:nosubs\", \"DAV:hassubs\"," +
|
String searchRequest = "Select \"DAV:nosubs\", \"DAV:hassubs\"," +
|
||||||
" \"DAV:hassubs\",\"urn:schemas:httpmail:unreadcount\"" +
|
" \"DAV:hassubs\",\"urn:schemas:httpmail:unreadcount\"" +
|
||||||
" FROM Scope('" + mode + " TRAVERSAL OF \"" + getFolderPath(folderName) + "\"')\n" +
|
" FROM Scope('" + mode + " TRAVERSAL OF \"" + getFolderPath(folderName) + "\"')\n" +
|
||||||
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = True \n"+
|
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = True \n" +
|
||||||
" AND (\"DAV:contentclass\"='urn:content-classes:mailfolder' OR \"DAV:contentclass\"='urn:content-classes:folder')";
|
" AND (\"DAV:contentclass\"='urn:content-classes:mailfolder' OR \"DAV:contentclass\"='urn:content-classes:folder')";
|
||||||
Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), mailPath, searchRequest);
|
Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), mailPath, searchRequest);
|
||||||
|
|
||||||
|
@ -830,14 +836,14 @@ public class ExchangeSession {
|
||||||
};
|
};
|
||||||
method.addPropertyToSet("outlookfolderclass", "IPF.Note", "ex", "http://schemas.microsoft.com/exchange/");
|
method.addPropertyToSet("outlookfolderclass", "IPF.Note", "ex", "http://schemas.microsoft.com/exchange/");
|
||||||
try {
|
try {
|
||||||
wdr.retrieveSessionInstance().executeMethod(method);
|
wdr.retrieveSessionInstance().executeMethod(method);
|
||||||
// ok or alredy exists
|
// ok or alredy exists
|
||||||
if (method.getStatusCode() != HttpStatus.SC_MULTI_STATUS && method.getStatusCode() != HttpStatus.SC_METHOD_NOT_ALLOWED) {
|
if (method.getStatusCode() != HttpStatus.SC_MULTI_STATUS && method.getStatusCode() != HttpStatus.SC_METHOD_NOT_ALLOWED) {
|
||||||
HttpException ex = new HttpException();
|
HttpException ex = new HttpException();
|
||||||
ex.setReasonCode(method.getStatusCode());
|
ex.setReasonCode(method.getStatusCode());
|
||||||
ex.setReason(method.getStatusText());
|
ex.setReason(method.getStatusText());
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
method.releaseConnection();
|
method.releaseConnection();
|
||||||
}
|
}
|
||||||
|
@ -847,19 +853,19 @@ public class ExchangeSession {
|
||||||
String folderPath = getFolderPath(folderName);
|
String folderPath = getFolderPath(folderName);
|
||||||
String targetPath = getFolderPath(targetName);
|
String targetPath = getFolderPath(targetName);
|
||||||
MoveMethod method = new MoveMethod(URIUtil.encodePath(folderPath),
|
MoveMethod method = new MoveMethod(URIUtil.encodePath(folderPath),
|
||||||
URIUtil.encodePath(targetPath));
|
URIUtil.encodePath(targetPath));
|
||||||
method.setOverwrite(false);
|
method.setOverwrite(false);
|
||||||
//method.addRequestHeader("Allow-Rename", "t");
|
//method.addRequestHeader("Allow-Rename", "t");
|
||||||
try {
|
try {
|
||||||
int statusCode = wdr.retrieveSessionInstance().executeMethod(method);
|
int statusCode = wdr.retrieveSessionInstance().executeMethod(method);
|
||||||
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
|
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
|
||||||
throw new HttpException("Unable to move folder, target already exists");
|
throw new HttpException("Unable to move folder, target already exists");
|
||||||
} else if (statusCode != HttpStatus.SC_CREATED) {
|
} else if (statusCode != HttpStatus.SC_CREATED) {
|
||||||
HttpException ex = new HttpException();
|
HttpException ex = new HttpException();
|
||||||
ex.setReasonCode(method.getStatusCode());
|
ex.setReasonCode(method.getStatusCode());
|
||||||
ex.setReason(method.getStatusText());
|
ex.setReason(method.getStatusText());
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
method.releaseConnection();
|
method.releaseConnection();
|
||||||
}
|
}
|
||||||
|
@ -885,13 +891,25 @@ public class ExchangeSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Message {
|
public class Message implements Comparable {
|
||||||
public String messageUrl;
|
public String messageUrl;
|
||||||
public String uid;
|
public String uid;
|
||||||
public int size;
|
public int size;
|
||||||
public String messageId;
|
public String messageId;
|
||||||
public boolean read;
|
public boolean read;
|
||||||
|
|
||||||
|
public long getUidAsLong() {
|
||||||
|
byte[] decodedValue = Base64.decode(uid.getBytes());
|
||||||
|
|
||||||
|
long result = 0;
|
||||||
|
for (int i = 2; i < 9; i++) {
|
||||||
|
result = result << 8;
|
||||||
|
result |= decodedValue[i] & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void write(OutputStream os) throws IOException {
|
public void write(OutputStream os) throws IOException {
|
||||||
HttpMethod method = null;
|
HttpMethod method = null;
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
|
@ -970,6 +988,23 @@ public class ExchangeSession {
|
||||||
LOGGER.debug("Deleted to :" + destination + " " + wdr.getStatusCode() + " " + wdr.getStatusMessage());
|
LOGGER.debug("Deleted to :" + destination + " " + wdr.getStatusCode() + " " + wdr.getStatusMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(Object message) {
|
||||||
|
return (int)(getUidAsLong()-((Message)message).getUidAsLong());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MessageList extends ArrayList<Message> {
|
||||||
|
HashMap<Long, Message> uidMessageMap = new HashMap<Long, Message>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Message message) {
|
||||||
|
uidMessageMap.put(message.getUidAsLong(), message);
|
||||||
|
return super.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message getByUid(long uid) {
|
||||||
|
return uidMessageMap.get(uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebdavResource getWebDavResource() {
|
public WebdavResource getWebDavResource() {
|
||||||
|
|
|
@ -170,6 +170,7 @@ public final class DavGatewayHttpClientFacade {
|
||||||
" <d:sql>" + searchRequest + "</d:sql>\n" +
|
" <d:sql>" + searchRequest + "</d:sql>\n" +
|
||||||
"</d:searchrequest>";
|
"</d:searchrequest>";
|
||||||
SearchMethod searchMethod = new SearchMethod(URIUtil.encodePath(folderUrl), searchBody);
|
SearchMethod searchMethod = new SearchMethod(URIUtil.encodePath(folderUrl), searchBody);
|
||||||
|
//searchMethod.setDebug(4);
|
||||||
try {
|
try {
|
||||||
int status = httpClient.executeMethod(searchMethod);
|
int status = httpClient.executeMethod(searchMethod);
|
||||||
// Also accept OK sent by buggy servers.
|
// Also accept OK sent by buggy servers.
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class ImapConnection extends AbstractConnection {
|
||||||
protected static final int AUTHENTICATED = 2;
|
protected static final int AUTHENTICATED = 2;
|
||||||
|
|
||||||
ExchangeSession.Folder currentFolder;
|
ExchangeSession.Folder currentFolder;
|
||||||
List<ExchangeSession.Message> messages;
|
ExchangeSession.MessageList messages;
|
||||||
|
|
||||||
// Initialize the streams and start the thread
|
// Initialize the streams and start the thread
|
||||||
public ImapConnection(Socket clientSocket) {
|
public ImapConnection(Socket clientSocket) {
|
||||||
|
@ -148,8 +148,13 @@ public class ImapConnection extends AbstractConnection {
|
||||||
messages = session.getAllMessages(currentFolder.folderUrl);
|
messages = session.getAllMessages(currentFolder.folderUrl);
|
||||||
sendClient("* " + currentFolder.objectCount + " EXISTS");
|
sendClient("* " + currentFolder.objectCount + " EXISTS");
|
||||||
sendClient("* " + currentFolder.objectCount + " RECENT");
|
sendClient("* " + currentFolder.objectCount + " RECENT");
|
||||||
sendClient("* OK [UIDVALIDITY " + currentFolder.lastModified + "]");
|
sendClient("* OK [UIDVALIDITY 1]");
|
||||||
sendClient("* OK [UIDNEXT " + (currentFolder.objectCount + 1) + "]");
|
if (messages.size() == 0) {
|
||||||
|
sendClient("* OK [UIDNEXT " + 1 + "]");
|
||||||
|
} else {
|
||||||
|
sendClient("* OK [UIDNEXT " + (messages.get(messages.size()-1).getUidAsLong()+1) + "]");
|
||||||
|
}
|
||||||
|
//sendClient("* OK [UIDNEXT " + (currentFolder.objectCount + 1) + "]");
|
||||||
sendClient("* FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded $MDNSent Forwarded $Junk $NotJunk Junk JunkRecorded NonJunk NotJunk)");
|
sendClient("* FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded $MDNSent Forwarded $Junk $NotJunk Junk JunkRecorded NonJunk NotJunk)");
|
||||||
sendClient("* OK [PERMANENTFLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded $MDNSent Forwarded \\*)] junk-related flags are not permanent");
|
sendClient("* OK [PERMANENTFLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded $MDNSent Forwarded \\*)] junk-related flags are not permanent");
|
||||||
//sendClient("* [UNSEEN 1] first unseen message in inbox");
|
//sendClient("* [UNSEEN 1] first unseen message in inbox");
|
||||||
|
@ -187,55 +192,72 @@ public class ImapConnection extends AbstractConnection {
|
||||||
if (currentFolder == null) {
|
if (currentFolder == null) {
|
||||||
sendClient(commandId + " NO no folder selected");
|
sendClient(commandId + " NO no folder selected");
|
||||||
}
|
}
|
||||||
int startIndex;
|
long startIndex;
|
||||||
int endIndex;
|
long endIndex;
|
||||||
int colonIndex = messageParameter.indexOf(":");
|
int colonIndex = messageParameter.lastIndexOf(":");
|
||||||
if (colonIndex < 0) {
|
if (colonIndex < 0) {
|
||||||
startIndex = endIndex = Integer.parseInt(messageParameter);
|
startIndex = endIndex = Long.parseLong(messageParameter);
|
||||||
} else {
|
} else {
|
||||||
startIndex = Integer.parseInt(messageParameter.substring(0, colonIndex));
|
int commaIndex = messageParameter.indexOf(",");
|
||||||
if (messageParameter.endsWith("*")) {
|
if (commaIndex > 0) {
|
||||||
endIndex = messages.size();
|
// workaround for multiple scopes : start at first and end at last
|
||||||
|
startIndex = Long.parseLong(messageParameter.substring(0, Math.min(commaIndex, messageParameter.indexOf(":"))));
|
||||||
} else {
|
} else {
|
||||||
endIndex = Integer.parseInt(messageParameter.substring(colonIndex + 1));
|
startIndex = Long.parseLong(messageParameter.substring(0, colonIndex));
|
||||||
|
}
|
||||||
|
if (messageParameter.endsWith("*")) {
|
||||||
|
if (messages.size() > 0) {
|
||||||
|
endIndex = messages.get(messages.size() - 1).getUidAsLong();
|
||||||
|
// fix according to spec
|
||||||
|
if (startIndex > endIndex) {
|
||||||
|
startIndex = endIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
endIndex = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
endIndex = Long.parseLong(messageParameter.substring(colonIndex + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("1:*".equals(messageParameter)) {
|
if ("1:*".equals(messageParameter)) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (ExchangeSession.Message message : messages) {
|
for (ExchangeSession.Message message : messages) {
|
||||||
count++;
|
count++;
|
||||||
sendClient("* " + count + " FETCH (UID " + count + " FLAGS ("+(message.read?"\\Seen":"")+"))");
|
sendClient("* " + count + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.read ? "\\Seen" : "") + "))");
|
||||||
}
|
}
|
||||||
sendClient(commandId + " OK UID FETCH completed");
|
sendClient(commandId + " OK UID FETCH completed");
|
||||||
} else {
|
} else {
|
||||||
if (tokens.hasMoreTokens()) {
|
if (tokens.hasMoreTokens()) {
|
||||||
String parameters = tokens.nextToken();
|
String parameters = tokens.nextToken();
|
||||||
for (int messageIndex = startIndex; messageIndex <= endIndex; messageIndex++) {
|
for (int messageIndex = 1; messageIndex <= messages.size(); messageIndex++) {
|
||||||
ExchangeSession.Message message = messages.get(messageIndex - 1);
|
ExchangeSession.Message message = messages.get(messageIndex - 1);
|
||||||
|
long uid = message.getUidAsLong();
|
||||||
|
if (uid >= startIndex && uid <= endIndex) {
|
||||||
|
|
||||||
if ("BODYSTRUCTURE".equals(parameters)) {
|
if ("BODYSTRUCTURE".equals(parameters)) {
|
||||||
sendClient("* " + messageIndex + " FETCH (BODYSTRUCTURE (\"TEXT\" \"PLAIN\" (\"CHARSET\" \"windows-1252\") NIL NIL \"QUOTED-PRINTABLE\" " + message.size + " 50 NIL NIL NIL NIL))");
|
sendClient("* " + messageIndex + " FETCH (BODYSTRUCTURE (\"TEXT\" \"PLAIN\" (\"CHARSET\" \"windows-1252\") NIL NIL \"QUOTED-PRINTABLE\" " + message.size + " 50 NIL NIL NIL NIL))");
|
||||||
} else if (parameters.indexOf("BODY[]") >= 0) {
|
} else if (parameters.indexOf("BODY[]") >= 0) {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
message.write(baos);
|
message.write(baos);
|
||||||
baos.close();
|
baos.close();
|
||||||
|
|
||||||
DavGatewayTray.debug("Messagee size: "+message.size+" actual size:"+baos.size()+" message+headers: "+(message.size+baos.size()));
|
DavGatewayTray.debug("Messagee size: " + message.size + " actual size:" + baos.size() + " message+headers: " + (message.size + baos.size()));
|
||||||
sendClient("* " + messageIndex + " FETCH (UID " + messageIndex + " RFC822.SIZE " + baos.size() + " BODY[]<0>" +
|
sendClient("* " + messageIndex + " FETCH (UID " + message.getUidAsLong() + " RFC822.SIZE " + baos.size() + " BODY[]<0>" +
|
||||||
" {" + baos.size() + "}");
|
" {" + baos.size() + "}");
|
||||||
message.write(os);
|
message.write(os);
|
||||||
sendClient(")");
|
sendClient(")");
|
||||||
} else {
|
} else {
|
||||||
// write headers to byte array
|
// write headers to byte array
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
HeaderOutputStream headerOutputStream = new HeaderOutputStream(baos);
|
HeaderOutputStream headerOutputStream = new HeaderOutputStream(baos);
|
||||||
message.write(headerOutputStream);
|
message.write(headerOutputStream);
|
||||||
baos.close();
|
baos.close();
|
||||||
sendClient("* " + messageIndex + " FETCH (UID " + messageIndex + " RFC822.SIZE " + headerOutputStream.size() + " BODY[HEADER.FIELDS ()" +
|
sendClient("* " + messageIndex + " FETCH (UID " + message.getUidAsLong() + " RFC822.SIZE " + headerOutputStream.size() + " BODY[HEADER.FIELDS ()" +
|
||||||
"] {" + baos.size() + "}");
|
"] {" + baos.size() + "}");
|
||||||
os.write(baos.toByteArray());
|
os.write(baos.toByteArray());
|
||||||
os.flush();
|
os.flush();
|
||||||
sendClient(" FLAGS ("+(message.read?"\\Seen":"")+"))");
|
sendClient(" FLAGS (" + (message.read ? "\\Seen" : "") + "))");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendClient(commandId + " OK FETCH completed");
|
sendClient(commandId + " OK FETCH completed");
|
||||||
|
@ -248,31 +270,31 @@ public class ImapConnection extends AbstractConnection {
|
||||||
} else if ("search".equalsIgnoreCase(subcommand)) {
|
} else if ("search".equalsIgnoreCase(subcommand)) {
|
||||||
// only create check search
|
// only create check search
|
||||||
String messageId = null;
|
String messageId = null;
|
||||||
int messageIndex = 0;
|
long messageUid = 0;
|
||||||
while (tokens.hasMoreTokens()) {
|
while (tokens.hasMoreTokens()) {
|
||||||
messageId = tokens.nextToken();
|
messageId = tokens.nextToken();
|
||||||
}
|
}
|
||||||
// reload messages
|
// reload messages
|
||||||
messages = session.getAllMessages(currentFolder.folderName);
|
messages = session.getAllMessages(currentFolder.folderName);
|
||||||
for (int i = 0; i < messages.size(); i++) {
|
for (ExchangeSession.Message message : messages) {
|
||||||
if (messageId.equals(messages.get(i).messageId)) {
|
if (messageId.equals(message.messageId)) {
|
||||||
messageIndex = i + 1;
|
messageUid = message.getUidAsLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (messageIndex > 0) {
|
if (messageUid > 0) {
|
||||||
sendClient("* SEARCH " + messageIndex);
|
sendClient("* SEARCH " + messageUid);
|
||||||
}
|
}
|
||||||
sendClient(commandId + " OK SEARCH completed");
|
sendClient(commandId + " OK SEARCH completed");
|
||||||
|
|
||||||
} else if ("store".equalsIgnoreCase(subcommand)) {
|
} else if ("store".equalsIgnoreCase(subcommand)) {
|
||||||
int uid = Integer.parseInt(tokens.nextToken());
|
long uid = Long.parseLong(tokens.nextToken());
|
||||||
String action = tokens.nextToken();
|
String action = tokens.nextToken();
|
||||||
String flags = tokens.nextToken();
|
String flags = tokens.nextToken();
|
||||||
HashMap<String, String> properties = new HashMap<String, String>();
|
HashMap<String, String> properties = new HashMap<String, String>();
|
||||||
if ("-Flags".equalsIgnoreCase(action)) {
|
if ("-Flags".equalsIgnoreCase(action)) {
|
||||||
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
||||||
while (flagtokenizer.hasMoreTokens()) {
|
while (flagtokenizer.hasMoreTokens()) {
|
||||||
String flag = flagtokenizer.nextToken();
|
String flag = flagtokenizer.nextToken();
|
||||||
if ("\\Seen".equals(flag)) {
|
if ("\\Seen".equals(flag)) {
|
||||||
properties.put("read", "0");
|
properties.put("read", "0");
|
||||||
}
|
}
|
||||||
|
@ -280,14 +302,14 @@ public class ImapConnection extends AbstractConnection {
|
||||||
} else if ("+Flags".equalsIgnoreCase(action)) {
|
} else if ("+Flags".equalsIgnoreCase(action)) {
|
||||||
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
||||||
while (flagtokenizer.hasMoreTokens()) {
|
while (flagtokenizer.hasMoreTokens()) {
|
||||||
String flag = flagtokenizer.nextToken();
|
String flag = flagtokenizer.nextToken();
|
||||||
if ("\\Seen".equals(flag)) {
|
if ("\\Seen".equals(flag)) {
|
||||||
properties.put("read", "1");
|
properties.put("read", "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO
|
// TODO
|
||||||
session.updateMessage(messages.get(uid-1), properties);
|
session.updateMessage(messages.getByUid(uid), properties);
|
||||||
sendClient(commandId + " OK STORE completed");
|
sendClient(commandId + " OK STORE completed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -340,13 +362,14 @@ public class ImapConnection extends AbstractConnection {
|
||||||
}
|
}
|
||||||
session.createMessage(session.getFolderPath(folderName), subject, null, new String(buffer), true);
|
session.createMessage(session.getFolderPath(folderName), subject, null, new String(buffer), true);
|
||||||
sendClient(commandId + " OK APPEND completed");
|
sendClient(commandId + " OK APPEND completed");
|
||||||
} else if ("noop".equalsIgnoreCase(command)) {
|
} else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) {
|
||||||
if (currentFolder != null) {
|
if (currentFolder != null) {
|
||||||
currentFolder = session.getFolder(currentFolder.folderName);
|
currentFolder = session.getFolder(currentFolder.folderName);
|
||||||
|
messages = session.getAllMessages(currentFolder.folderUrl);
|
||||||
sendClient("* " + currentFolder.objectCount + " EXISTS");
|
sendClient("* " + currentFolder.objectCount + " EXISTS");
|
||||||
sendClient("* " + currentFolder.objectCount + " RECENT");
|
sendClient("* " + currentFolder.objectCount + " RECENT");
|
||||||
}
|
}
|
||||||
sendClient(commandId + " OK NOOP completed");
|
sendClient(commandId + " OK " + command + " completed");
|
||||||
} else {
|
} else {
|
||||||
sendClient(commandId + " BAD command unrecognized");
|
sendClient(commandId + " BAD command unrecognized");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue