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

IMAP: search implementation

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@368 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-02-17 22:59:32 +00:00
parent e0a65766db
commit cd20a970ce
2 changed files with 96 additions and 27 deletions

View File

@ -619,6 +619,9 @@ public class ExchangeSession {
}
public MessageList getAllMessages(String folderName) throws IOException {
return searchMessages(folderName, "");
}
public MessageList searchMessages(String folderName, String conditions) throws IOException {
String folderUrl = getFolderPath(folderName);
MessageList messages = new MessageList();
String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
@ -627,6 +630,7 @@ public class ExchangeSession {
" ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\", \"DAV:isdeleted\"" +
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" +
conditions+
" ORDER BY \"urn:schemas:httpmail:date\" ASC";
Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), folderUrl, searchRequest);

View File

@ -17,6 +17,7 @@ import java.net.SocketTimeoutException;
import java.net.SocketException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
/**
* Dav Gateway smtp connection implementation.
@ -48,21 +49,7 @@ public class ImapConnection extends AbstractConnection {
break;
}
tokens = new StringTokenizer(line) {
public String nextToken() {
StringBuilder nextToken = new StringBuilder();
nextToken.append(super.nextToken());
while (hasMoreTokens() && nextToken.length() > 0 && nextToken.charAt(0) == '"'
&& 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 removeQuotes(nextToken.toString());
}
};
tokens = new IMAPTokenizer(line);
if (tokens.hasMoreTokens()) {
commandId = tokens.nextToken();
if (tokens.hasMoreTokens()) {
@ -240,21 +227,38 @@ public class ImapConnection extends AbstractConnection {
}
} else if ("search".equalsIgnoreCase(subcommand)) {
// only create check search
String messageId = null;
long messageUid = 0;
StringBuilder conditions = new StringBuilder();
boolean undeleted = true;
while (tokens.hasMoreTokens()) {
messageId = tokens.nextToken();
}
// reload messages
messages = session.getAllMessages(currentFolder.folderName);
for (ExchangeSession.Message message : messages) {
if (messageId.equals(message.messageId)) {
messageUid = message.getUidAsLong();
String token = tokens.nextToken();
if ("UNDELETED".equals(token)) {
undeleted = true;
} else if (token.startsWith("OR ")) {
conditions.append(" AND (");
IMAPTokenizer innerTokens = new IMAPTokenizer(token);
innerTokens.nextToken();
boolean first = true;
while (innerTokens.hasMoreTokens()) {
String innerToken = innerTokens.nextToken();
if (!first) {
conditions.append(" OR ");
}
first = false;
appendSearchParam(innerTokens, innerToken, conditions);
}
conditions.append(")");
} else {
conditions.append(" AND ");
appendSearchParam(tokens, token, conditions);
}
}
if (messageUid > 0) {
sendClient("* SEARCH " + messageUid);
messages = session.searchMessages(currentFolder.folderName, conditions.toString());
for (ExchangeSession.Message message : messages) {
if ((undeleted && !message.deleted) || !undeleted) {
sendClient("* SEARCH " + message.getUidAsLong());
}
}
sendClient(commandId + " OK SEARCH completed");
@ -427,6 +431,45 @@ public class ImapConnection extends AbstractConnection {
DavGatewayTray.resetIcon();
}
private void appendSearchParam(StringTokenizer tokens, String token, StringBuilder conditions) throws IOException {
if ("NOT".equals(token)) {
conditions.append(" NOT ");
appendSearchParam(tokens, tokens.nextToken(), conditions);
} else if ("SUBJECT".equals(token)) {
conditions.append("\"urn:schemas:httpmail:subject\" LIKE '%").append(tokens.nextToken()).append("%'");
} else if ("BODY".equals(token)) {
conditions.append("\"http://schemas.microsoft.com/mapi/proptag/x01000001E\" LIKE '%").append(tokens.nextToken()).append("%'");
} else if ("FROM".equals(token)) {
conditions.append("\"urn:schemas:mailheader:from\" LIKE '%").append(tokens.nextToken()).append("%'");
} else if ("SENTON".equals(token)) {
SimpleDateFormat parser = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH);
parser.setTimeZone(ExchangeSession.GMT_TIMEZONE);
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateFormatter.setTimeZone(ExchangeSession.GMT_TIMEZONE);
try {
Date startDate = parser.parse(tokens.nextToken());
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
calendar.add(Calendar.DAY_OF_MONTH, 1);
conditions.append("(\"urn:schemas:httpmail:date\" > '")
.append(dateFormatter.format(startDate))
.append("' AND \"urn:schemas:httpmail:date\" < '")
.append(dateFormatter.format(calendar.getTime()))
.append("')");
} catch (ParseException e) {
throw new IOException("Invalid search parameters");
}
} else if ("HEADER".equals(token)) {
String headerName = tokens.nextToken();
if ("Message-ID".equalsIgnoreCase(headerName)) {
conditions.append("\"urn:schemas:mailheader:message-id\"='").append(tokens.nextToken()).append("'");
}
} else {
throw new IOException("Invalid search parameters");
}
}
protected void expunge() throws IOException {
if (messages != null) {
int index = 0;
@ -627,4 +670,26 @@ public class ImapConnection extends AbstractConnection {
throw new UnsupportedOperationException();
}
}
class IMAPTokenizer extends StringTokenizer {
public IMAPTokenizer(String value) {
super(value);
}
@Override
public String nextToken() {
StringBuilder nextToken = new StringBuilder();
nextToken.append(super.nextToken());
while (hasMoreTokens() && nextToken.length() > 0 && nextToken.charAt(0) == '"'
&& 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 removeQuotes(nextToken.toString());
}
}
}