1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-08-13 16:53:51 -04:00

IMAP message list and fetch now working

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@302 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-01-23 10:30:48 +00:00
parent 09de523391
commit f2e19291ab
2 changed files with 125 additions and 24 deletions

View File

@ -61,10 +61,21 @@ public class ExchangeSession {
WELL_KNOWN_FOLDERS.add("urn:schemas:httpmail:calendar");
}
public static final HashMap<String, String> PRIORITIES = new HashMap<String, String>();
static {
PRIORITIES.put("-2", "5 (Lowest)");
PRIORITIES.put("-1", "4 (Low)");
PRIORITIES.put("1", "2 (High)");
PRIORITIES.put("2", "1 (Highest)");
}
/**
* Date parser from Exchange format
* Date parser/formatter from Exchange format
*/
private final SimpleDateFormat dateFormatter;
private final SimpleDateFormat dateParser;
/**
* Various standard mail boxes Urls
@ -102,6 +113,10 @@ public class ExchangeSession {
// SimpleDateFormat are not thread safe, need to create one instance for
// each session
dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
dateParser.setTimeZone(GMT_TIMEZONE);
LOGGER.debug("Session " + this + " created");
}
@ -513,6 +528,23 @@ public class ExchangeSession {
message.size = Integer.parseInt(prop.getPropertyAsString());
} else if ("uid".equals(localName)) {
message.uid = prop.getPropertyAsString();
} else if ("date".equals(prop.getLocalName())) {
message.date = prop.getPropertyAsString();
} else if ("message-id".equals(prop.getLocalName())) {
message.messageId = prop.getPropertyAsString();
} else if ("from".equals(prop.getLocalName())) {
message.from = prop.getPropertyAsString();
} else if ("to".equals(prop.getLocalName())) {
message.to = prop.getPropertyAsString();
} else if ("cc".equals(prop.getLocalName())) {
message.cc = prop.getPropertyAsString();
} else if ("subject".equals(prop.getLocalName())) {
message.subject = prop.getPropertyAsString();
} else if ("priority".equals(prop.getLocalName())) {
String priorityLabel = PRIORITIES.get(prop.getPropertyAsString());
if (priorityLabel != null) {
message.priority = priorityLabel;
}
}
}
@ -538,6 +570,7 @@ public class ExchangeSession {
String folderUrl = getFolderPath(folderName);
List<Message> messages = new ArrayList<Message>();
String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
" ,\"urn:schemas:mailheader:from\",\"urn:schemas:mailheader:to\",\"urn:schemas:mailheader:cc\",\"urn:schemas:httpmail:subject\",\"urn:schemas:mailheader:date\",\"urn:schemas:mailheader:message-id\",\"urn:schemas:httpmail:priority\""+
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" +
" ORDER BY \"urn:schemas:httpmail:date\" ASC";
@ -552,11 +585,12 @@ public class ExchangeSession {
return messages;
}
public List<Folder> getSubFolders(String folderName) throws IOException {
public List<Folder> getSubFolders(String folderName,boolean recursive) throws IOException {
String mode = recursive?"DEEP":"SHALLOW";
List<Folder> folders = new ArrayList<Folder>();
String searchRequest = "Select \"DAV:nosubs\", \"DAV:hassubs\"," +
" \"DAV:hassubs\",\"urn:schemas:httpmail:unreadcount\"" +
" FROM Scope('SHALLOW TRAVERSAL OF \"" + getFolderPath(folderName) + "\"')\n" +
" FROM Scope('"+mode+" TRAVERSAL OF \"" + getFolderPath(folderName) + "\"')\n" +
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = True \n";
Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), mailPath, searchRequest);
@ -585,7 +619,13 @@ public class ExchangeSession {
if ("unreadcount".equals(property.getLocalName())) {
folder.unreadCount = Integer.parseInt(property.getPropertyAsString());
}
if ("getlastmodified".equals(property.getLocalName())) {
try {
folder.lastModified = dateParser.parse(property.getPropertyAsString()).getTime();
} catch (ParseException e) {
LOGGER.error("Unable to parse date: "+e);
}
}
}
if (href.endsWith("/")) {
href = href.substring(0, href.length()-1);
@ -757,6 +797,7 @@ public class ExchangeSession {
reqProps.add("DAV:nosubs");
reqProps.add("DAV:objectcount");
reqProps.add("urn:schemas:httpmail:unreadcount");
reqProps.add("DAV:getlastmodified");
Enumeration folderEnum = wdr.propfindMethod(folder.folderUrl, 0, reqProps);
if (folderEnum.hasMoreElements()) {
@ -772,6 +813,7 @@ public class ExchangeSession {
public int unreadCount;
public boolean hasChildren;
public boolean noInferiors;
public long lastModified;
public String getFlags() {
if (noInferiors) {
@ -788,6 +830,13 @@ public class ExchangeSession {
public String messageUrl;
public String uid;
public int size;
public String from;
public String date;
public String messageId;
public String subject;
public String priority;
public String cc;
public String to;
public void write(OutputStream os) throws IOException {
HttpMethod method = null;

View File

@ -6,6 +6,7 @@ import java.net.SocketException;
import java.util.StringTokenizer;
import java.util.List;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import davmail.AbstractConnection;
import davmail.tray.DavGatewayTray;
@ -50,6 +51,10 @@ public class ImapConnection extends AbstractConnection {
&& nextToken.charAt(nextToken.length() - 1) != '"') {
nextToken.append(' ').append(super.nextToken());
}
while (hasMoreTokens() && nextToken.length() > 0 && nextToken.charAt(0) == '('
&& nextToken.charAt(nextToken.length() - 1) != ')') {
nextToken.append(' ').append(super.nextToken());
}
return nextToken.toString();
}
};
@ -103,24 +108,26 @@ public class ImapConnection extends AbstractConnection {
if (state != AUTHENTICATED) {
sendClient(commandId + " BAD command authentication required");
} else {
if ("lsub".equalsIgnoreCase(command)) {
sendClient(commandId + " OK LSUB completed");
} else if ("list".equalsIgnoreCase(command)) {
if ("lsub".equalsIgnoreCase(command) || "list".equalsIgnoreCase(command)) {
if (tokens.hasMoreTokens()) {
String folderContext = BASE64MailboxDecoder.decode(removeQuotes(tokens.nextToken()));
if (tokens.hasMoreTokens()) {
String folderQuery = folderContext + BASE64MailboxDecoder.decode(removeQuotes(tokens.nextToken()));
if (folderQuery.endsWith("%")) {
List<ExchangeSession.Folder> folders = session.getSubFolders(folderQuery.substring(0, folderQuery.length() - 1));
if (folderQuery.endsWith("%/%")) {
folderQuery = folderQuery.substring(0, folderQuery.length() - 2);
}
if (folderQuery.endsWith("%") || folderQuery.endsWith("*")) {
boolean recursive = folderQuery.endsWith("*");
List<ExchangeSession.Folder> folders = session.getSubFolders(folderQuery.substring(0, folderQuery.length() - 1), recursive);
for (ExchangeSession.Folder folder : folders) {
sendClient("* LIST (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderUrl) + "\"");
sendClient("* " + command + " (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderUrl) + "\"");
}
sendClient(commandId + " OK LIST completed");
sendClient(commandId + " OK " + command + " completed");
} else {
ExchangeSession.Folder folder = session.getFolder(folderQuery);
if (folder != null) {
sendClient("* LIST (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderUrl) + "\"");
sendClient(commandId + " OK LIST completed");
sendClient("* " + command + " (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderUrl) + "\"");
sendClient(commandId + " OK " + command + " completed");
} else {
sendClient(commandId + " NO Folder not found");
}
@ -138,11 +145,11 @@ public class ImapConnection extends AbstractConnection {
messages = session.getAllMessages(currentFolder.folderUrl);
sendClient("* " + currentFolder.objectCount + " EXISTS");
sendClient("* " + currentFolder.objectCount + " RECENT");
sendClient("* OK [UIDVALIDITY " + System.currentTimeMillis() + "]");
sendClient("* OK [UIDVALIDITY " + currentFolder.lastModified + "]");
sendClient("* OK [UIDNEXT " + (currentFolder.objectCount + 1) + "]");
sendClient("* FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen)");
sendClient("* OK [PERMANENTFLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen)]");
sendClient("* [UNSEEN 1] first unseen message in inbox");
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("* [UNSEEN 1] first unseen message in inbox");
sendClient(commandId + " OK [READ-WRITE] " + command + " completed");
} else {
sendClient(commandId + " BAD command unrecognized");
@ -166,17 +173,60 @@ public class ImapConnection extends AbstractConnection {
} else if ("uid".equalsIgnoreCase(command)) {
if (tokens.hasMoreTokens() && "fetch".equalsIgnoreCase(tokens.nextToken())) {
if (tokens.hasMoreTokens()) {
String parameter = tokens.nextToken();
String messageParameter = tokens.nextToken();
if (currentFolder == null) {
sendClient(commandId + " NO no folder selected");
}
if ("1:*".equals(parameter)) {
for (int i = 0; i < currentFolder.objectCount; i++) {
sendClient("* FETCH (UID " + (i + 1) + " FLAGS (\\Recent))");
int startIndex;
int endIndex;
int colonIndex = messageParameter.indexOf(":");
if (colonIndex < 0) {
startIndex = endIndex = Integer.parseInt(messageParameter);
} else {
startIndex = Integer.parseInt(messageParameter.substring(0, colonIndex));
if (messageParameter.endsWith("*")) {
endIndex = messages.size();
} else {
endIndex = Integer.parseInt(messageParameter.substring(colonIndex + 1));
}
}
if ("1:*".equals(messageParameter)) {
int count = 0;
for (ExchangeSession.Message message : messages) {
count++;
sendClient("* " + count + " FETCH (UID " + count + " FLAGS (\\Seen))");
}
sendClient(commandId + " OK UID FETCH completed");
} else {
sendClient(commandId + " BAD command unrecognized");
if (tokens.hasMoreTokens()) {
String parameters = tokens.nextToken();
for (int messageIndex = startIndex; messageIndex <= endIndex; messageIndex++) {
ExchangeSession.Message message = messages.get(messageIndex - 1);
if ("(BODYSTRUCTURE)".equals(parameters)) {
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) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
message.write(baos);
baos.close();
sendClient("* " + messageIndex + " FETCH (UID " + messageIndex + " RFC822.SIZE " + baos.size() + " BODY[]<0>" +
" {" + baos.size() + "}");
message.write(os);
sendClient(")");
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
message.write(baos);
baos.close();
sendClient("* " + messageIndex + " FETCH (UID " + messageIndex + " RFC822.SIZE " + baos.size() + " BODY[HEADER.FIELDS (FROM TO CC SUBJECT DATE MESSAGE-ID PRIORITY X-PRIORITY REFERENCES NEWSGROUPS IN-REPLY-TO CONTENT-TYPE)" +
"] {" + baos.size() + "}");
message.write(os);
sendClient(" FLAGS (\\Seen))");
}
}
sendClient(commandId + " OK FETCH completed");
}
}
} else {
sendClient(commandId + " BAD command unrecognized");
@ -191,15 +241,17 @@ public class ImapConnection extends AbstractConnection {
if (tokens.hasMoreTokens()) {
String parameters = tokens.nextToken();
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))");
sendClient(commandId + " OK FETCH completed");
} else {
sendClient("* "+messageIndex+" 1 FETCH (BODY[TEXT]<0> {" + message.size + "}");
sendClient("* " + messageIndex + " 1 FETCH (BODY[TEXT]<0> {" + message.size + "}");
message.write(os);
sendClient(commandId + " OK FETCH completed");
}
}
}
} else if ("noop".equalsIgnoreCase(command)) {
sendClient(commandId + " OK NOOP completed");
} else {
sendClient(commandId + " BAD command unrecognized");
}