From eba0e0fded50e6fbc4b98d7245ffebb4e6114cad Mon Sep 17 00:00:00 2001 From: mguessan Date: Mon, 23 Feb 2009 17:42:49 +0000 Subject: [PATCH] Refactor IMAP fetch to handle more cases (still broken with Outlook) git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@392 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../davmail/exchange/ExchangeSession.java | 5 +- src/java/davmail/imap/ImapConnection.java | 69 ++++++++++++------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 5e565793..74b68b55 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -546,6 +546,8 @@ public class ExchangeSession { } else if ("x10810003".equals(localName)) { message.answered = "102".equals(prop.getPropertyAsString()) || "103".equals(prop.getPropertyAsString()); message.forwarded = "104".equals(prop.getPropertyAsString()); + } else if ("date".equals(prop.getLocalName())) { + message.date = prop.getPropertyAsString(); } else if ("isdeleted".equals(localName)) { message.deleted = "1".equals(prop.getPropertyAsString()); } else if ("message-id".equals(prop.getLocalName())) { @@ -628,7 +630,7 @@ public class ExchangeSession { String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" + " ,\"http://schemas.microsoft.com/mapi/proptag/x10830003\", \"http://schemas.microsoft.com/mapi/proptag/x10900003\"" + " ,\"http://schemas.microsoft.com/mapi/proptag/x0E070003\", \"http://schemas.microsoft.com/mapi/proptag/x10810003\"" + - " ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\", \"DAV:isdeleted\"" + + " ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\", \"DAV:isdeleted\", \"urn:schemas:mailheader:date\"" + " FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" + " WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" + conditions.replaceAll("<", "<").replaceAll(">", ">") + @@ -963,6 +965,7 @@ public class ExchangeSession { public String uid; public int size; public String messageId; + public String date; public boolean read; public boolean deleted; public boolean junk; diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java index 3d345e8d..532f3bc4 100644 --- a/src/java/davmail/imap/ImapConnection.java +++ b/src/java/davmail/imap/ImapConnection.java @@ -425,34 +425,51 @@ public class ImapConnection extends AbstractConnection { } private void handleFetch(ExchangeSession.Message message, int currentIndex, String parameters) throws IOException { - if (parameters == null || "FLAGS".equals(parameters) || "FLAGS UID".equals(parameters)) { - sendClient("* " + (currentIndex) + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.getImapFlags()) + "))"); - } else if ("BODYSTRUCTURE".equals(parameters)) { - sendClient("* " + (currentIndex) + " FETCH (UID " + message.getUidAsLong() + " BODYSTRUCTURE (\"TEXT\" \"PLAIN\" (\"CHARSET\" \"windows-1252\") NIL NIL \"QUOTED-PRINTABLE\" " + message.size + " 50 NIL NIL NIL NIL))"); - // send full message - } else if (parameters.indexOf("BODY[]") >= 0 || parameters.indexOf("BODY.PEEK[]") >= 0 || "BODY.PEEK[TEXT]".equals(parameters)) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - message.write(baos); - baos.close(); + StringBuilder buffer = new StringBuilder(); + buffer.append("* " + (currentIndex) + " FETCH (UID " + message.getUidAsLong()); - DavGatewayTray.debug("Message size: " + message.size + " actual size:" + baos.size() + " message+headers: " + (message.size + baos.size())); - sendClient("* " + (currentIndex) + " FETCH (UID " + message.getUidAsLong() + " RFC822.SIZE " + baos.size() + " BODY[]<0>" + - " {" + baos.size() + "}"); - os.write(baos.toByteArray()); - os.flush(); - sendClient(")"); - } else { - // write headers to byte array - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - HeaderOutputStream headerOutputStream = new HeaderOutputStream(baos); - message.write(headerOutputStream); - baos.close(); - sendClient("* " + (currentIndex) + " FETCH (UID " + message.getUidAsLong() + " RFC822.SIZE " + headerOutputStream.size() + " BODY[HEADER.FIELDS ()" + - "] {" + baos.size() + "}"); - os.write(baos.toByteArray()); - os.flush(); - sendClient(" FLAGS (" + (message.getImapFlags()) + "))"); + StringTokenizer paramTokens = new StringTokenizer(parameters); + while (paramTokens.hasMoreTokens()) { + String param = paramTokens.nextToken(); + if ("FLAGS".equals(param)) { + buffer.append(" FLAGS (" + (message.getImapFlags()) + ")"); + } else if ("BODYSTRUCTURE".equals(param)) { + buffer.append(" BODYSTRUCTURE (\"TEXT\" \"PLAIN\" (\"CHARSET\" \"windows-1252\") NIL NIL \"QUOTED-PRINTABLE\" " + message.size + " 50 NIL NIL NIL NIL))"); + } else if ("INTERNALDATE".equals(param)) { + try { + SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + dateParser.setTimeZone(ExchangeSession.GMT_TIMEZONE); + Date date = null; + date = dateParser.parse(message.date); + SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.ENGLISH); + buffer.append(" INTERNALDATE \"" + dateFormatter.format(date) + "\""); + } catch (ParseException e) { + throw new IOException("Invalid date: " + message.date); + } + } else if ("BODY[]".equals(param) || "BODY.PEEK[]".equals(param)) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + message.write(baos); + baos.close(); + DavGatewayTray.debug("Message size: " + message.size + " actual size:" + baos.size() + " message+headers: " + (message.size + baos.size())); + buffer.append(" RFC822.SIZE " + baos.size() + " " + param + "<0> {" + (baos.size()-4) + "}"); + sendClient(buffer.toString()); + os.write(baos.toByteArray(), 0, baos.toByteArray().length-4); + os.flush(); + buffer.setLength(0); + } else if ("BODY.PEEK[HEADER]".equals(param) || param.startsWith("BODY.PEEK[HEADER")) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + HeaderOutputStream headerOutputStream = new HeaderOutputStream(baos); + message.write(headerOutputStream); + baos.close(); + buffer.append(" RFC822.SIZE " + baos.size() + " BODY[HEADER.FIELDS ()] {" + baos.size() + "}"); + sendClient(buffer.toString()); + os.write(baos.toByteArray()); + os.flush(); + buffer.setLength(0); + } } + buffer.append(")"); + sendClient(buffer.toString()); } static final class SearchConditions {