mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 03:02:22 -05:00
Fix conflict between Draft and bcc PROPATCH
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@325 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
d578aa889d
commit
db381db85b
@ -458,40 +458,28 @@ public class ExchangeSession {
|
|||||||
*
|
*
|
||||||
* @param folderUrl Exchange folder URL
|
* @param folderUrl Exchange folder URL
|
||||||
* @param messageName message name
|
* @param messageName message name
|
||||||
* @param bcc blind carbon copy header
|
* @param properties message properties (flags)
|
||||||
* @param messageBody mail body
|
* @param messageBody mail body
|
||||||
* @param allowOverwrite allow existing message overwrite
|
* @param allowOverwrite allow existing message overwrite
|
||||||
* @throws java.io.IOException when unable to create message
|
* @throws java.io.IOException when unable to create message
|
||||||
*/
|
*/
|
||||||
public void createMessage(String folderUrl, String messageName, String bcc, String messageBody, boolean allowOverwrite) throws IOException {
|
public void createMessage(String folderUrl, String messageName, HashMap<String, String> properties, String messageBody, boolean allowOverwrite) throws IOException {
|
||||||
String messageUrl = URIUtil.encodePathQuery(folderUrl + "/" + messageName + ".EML");
|
String messageUrl = URIUtil.encodePathQuery(folderUrl + "/" + messageName + ".EML");
|
||||||
|
PropPatchMethod patchMethod;
|
||||||
// create the message first as draft
|
// create the message first as draft
|
||||||
PropPatchMethod patchMethod = new PropPatchMethod(messageUrl);
|
if (properties.containsKey("draft")) {
|
||||||
if (!allowOverwrite) {
|
patchMethod = new PropPatchMethod(messageUrl);
|
||||||
patchMethod.setRequestHeader("If-None-Match", "*");
|
try {
|
||||||
}
|
// update message with blind carbon copy and other flags
|
||||||
try {
|
addProperties(patchMethod, properties);
|
||||||
// update message with blind carbon copy
|
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
||||||
if (bcc != null && bcc.length() > 0) {
|
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
||||||
patchMethod.addPropertyToSet("bcc", bcc, "b", "urn:schemas:mailheader:");
|
throw new IOException("Unable to create message " + messageUrl + ": " + statusCode + " " + patchMethod.getStatusLine());
|
||||||
}
|
|
||||||
patchMethod.addPropertyToSet("x0E070003", "9", "d", "http://schemas.microsoft.com/mapi/proptag/");
|
|
||||||
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
|
||||||
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
|
||||||
throw new IOException("Unable to add bcc recipients: " + bcc);
|
|
||||||
}
|
|
||||||
Enumeration responseEntityEnum = patchMethod.getResponses();
|
|
||||||
|
|
||||||
if (responseEntityEnum.hasMoreElements()) {
|
|
||||||
ResponseEntity entity = (ResponseEntity) responseEntityEnum.nextElement();
|
|
||||||
if (entity.getStatusCode() != HttpStatus.SC_OK) {
|
|
||||||
throw new IOException("Unable to add bcc recipients: " + bcc);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
patchMethod.releaseConnection();
|
patchMethod.releaseConnection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PutMethod putmethod = new PutMethod(messageUrl);
|
PutMethod putmethod = new PutMethod(messageUrl);
|
||||||
@ -504,7 +492,7 @@ public class ExchangeSession {
|
|||||||
putmethod.setRequestBody(bodyStream);
|
putmethod.setRequestBody(bodyStream);
|
||||||
int code = wdr.retrieveSessionInstance().executeMethod(putmethod);
|
int code = wdr.retrieveSessionInstance().executeMethod(putmethod);
|
||||||
|
|
||||||
if (code != HttpURLConnection.HTTP_OK) {
|
if (code != HttpStatus.SC_OK && code != HttpStatus.SC_CREATED) {
|
||||||
throw new IOException("Unable to create message " + messageUrl + ": " + code + " " + putmethod.getStatusLine());
|
throw new IOException("Unable to create message " + messageUrl + ": " + code + " " + putmethod.getStatusLine());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -518,6 +506,19 @@ public class ExchangeSession {
|
|||||||
putmethod.releaseConnection();
|
putmethod.releaseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add bcc and other properties
|
||||||
|
patchMethod = new PropPatchMethod(messageUrl);
|
||||||
|
try {
|
||||||
|
// update message with blind carbon copy and other flags
|
||||||
|
addProperties(patchMethod, properties);
|
||||||
|
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
||||||
|
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
||||||
|
throw new IOException("Unable to patch message " + messageUrl + ": " + statusCode + " " + patchMethod.getStatusLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
patchMethod.releaseConnection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message buildMessage(ResponseEntity responseEntity) throws URIException {
|
protected Message buildMessage(ResponseEntity responseEntity) throws URIException {
|
||||||
@ -540,6 +541,8 @@ public class ExchangeSession {
|
|||||||
message.flagged = "2".equals(prop.getPropertyAsString());
|
message.flagged = "2".equals(prop.getPropertyAsString());
|
||||||
} else if ("x0E070003".equals(localName)) {
|
} else if ("x0E070003".equals(localName)) {
|
||||||
message.draft = "9".equals(prop.getPropertyAsString());
|
message.draft = "9".equals(prop.getPropertyAsString());
|
||||||
|
} else if ("x10810003".equals(localName)) {
|
||||||
|
message.answered = prop.getPropertyAsString().length() > 0;
|
||||||
} 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(">")) {
|
if (message.messageId.startsWith("<") && message.messageId.endsWith(">")) {
|
||||||
@ -566,18 +569,28 @@ public class ExchangeSession {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void addProperties(PropPatchMethod patchMethod, Map<String, String> properties) {
|
||||||
|
for (Map.Entry<String, String> entry : properties.entrySet()) {
|
||||||
|
if ("read".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("read", entry.getValue(), "e", "urn:schemas:httpmail:");
|
||||||
|
} else if ("junk".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("x10830003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
||||||
|
} else if ("flagged".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("x10900003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
||||||
|
} else if ("answered".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("x10810003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
||||||
|
} else if ("bcc".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("bcc", entry.getValue(), "b", "urn:schemas:mailheader:");
|
||||||
|
} else if ("draft".equals(entry.getKey())) {
|
||||||
|
patchMethod.addPropertyToSet("x0E070003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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()) {
|
addProperties(patchMethod, properties);
|
||||||
if ("read".equals(entry.getKey())) {
|
|
||||||
patchMethod.addPropertyToSet("read", entry.getValue(), "e", "urn:schemas:httpmail:");
|
|
||||||
} else if ("junk".equals(entry.getKey())) {
|
|
||||||
patchMethod.addPropertyToSet("x10830003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
|
||||||
} else if ("flagged".equals(entry.getKey())) {
|
|
||||||
patchMethod.addPropertyToSet("x10900003", entry.getValue(), "f", "http://schemas.microsoft.com/mapi/proptag/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
int statusCode = wdr.retrieveSessionInstance().executeMethod(patchMethod);
|
||||||
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
|
||||||
throw new IOException("Unable to update message properties");
|
throw new IOException("Unable to update message properties");
|
||||||
@ -593,7 +606,7 @@ public class ExchangeSession {
|
|||||||
MessageList messages = new MessageList();
|
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\"" +
|
||||||
" ,\"http://schemas.microsoft.com/mapi/proptag/x10830003\", \"http://schemas.microsoft.com/mapi/proptag/x10900003\"" +
|
" ,\"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/x0E070003\", \"http://schemas.microsoft.com/mapi/proptag/x10810003\"" +
|
||||||
" ,\"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" +
|
||||||
@ -770,11 +783,15 @@ public class ExchangeSession {
|
|||||||
bccBuffer.append(">");
|
bccBuffer.append(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String bcc = bccBuffer.toString();
|
||||||
|
HashMap<String, String> properties = new HashMap<String, String>();
|
||||||
|
if (bcc.length() > 0) {
|
||||||
|
properties.put("bcc", bcc);
|
||||||
|
}
|
||||||
|
|
||||||
String messageName = UUID.randomUUID().toString();
|
String messageName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
createMessage(draftsUrl, messageName,
|
createMessage(draftsUrl, messageName, properties, mailBuffer.toString(), false);
|
||||||
bccBuffer.toString()
|
|
||||||
, mailBuffer.toString(), false);
|
|
||||||
|
|
||||||
// warning : slide library expects *unencoded* urls
|
// warning : slide library expects *unencoded* urls
|
||||||
String tempUrl = draftsUrl + "/" + messageName + ".EML";
|
String tempUrl = draftsUrl + "/" + messageName + ".EML";
|
||||||
@ -925,6 +942,7 @@ public class ExchangeSession {
|
|||||||
public boolean junk;
|
public boolean junk;
|
||||||
public boolean flagged;
|
public boolean flagged;
|
||||||
public boolean draft;
|
public boolean draft;
|
||||||
|
public boolean answered;
|
||||||
|
|
||||||
public long getUidAsLong() {
|
public long getUidAsLong() {
|
||||||
byte[] decodedValue = Base64.decode(uid.getBytes());
|
byte[] decodedValue = Base64.decode(uid.getBytes());
|
||||||
@ -955,6 +973,9 @@ public class ExchangeSession {
|
|||||||
if (draft) {
|
if (draft) {
|
||||||
buffer.append("\\Draft ");
|
buffer.append("\\Draft ");
|
||||||
}
|
}
|
||||||
|
if (answered) {
|
||||||
|
buffer.append("\\Answered ");
|
||||||
|
}
|
||||||
return buffer.toString().trim();
|
return buffer.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,43 +303,7 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
ExchangeSession.Message message = messages.getByUid(uid);
|
ExchangeSession.Message message = messages.getByUid(uid);
|
||||||
String action = tokens.nextToken();
|
String action = tokens.nextToken();
|
||||||
String flags = tokens.nextToken();
|
String flags = tokens.nextToken();
|
||||||
HashMap<String, String> properties = new HashMap<String, String>();
|
updateFlags(message, action, flags);
|
||||||
if ("-Flags".equalsIgnoreCase(action)) {
|
|
||||||
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
|
||||||
while (flagtokenizer.hasMoreTokens()) {
|
|
||||||
String flag = flagtokenizer.nextToken();
|
|
||||||
if ("\\Seen".equals(flag)) {
|
|
||||||
properties.put("read", "0");
|
|
||||||
message.read = false;
|
|
||||||
} else if ("\\Flagged".equals(flag)) {
|
|
||||||
properties.put("flagged", "0");
|
|
||||||
message.flagged = false;
|
|
||||||
} else if ("Junk".equals(flag)) {
|
|
||||||
properties.put("junk", "0");
|
|
||||||
message.junk = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ("+Flags".equalsIgnoreCase(action)) {
|
|
||||||
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
|
||||||
while (flagtokenizer.hasMoreTokens()) {
|
|
||||||
String flag = flagtokenizer.nextToken();
|
|
||||||
if ("\\Seen".equals(flag)) {
|
|
||||||
properties.put("read", "1");
|
|
||||||
message.read = true;
|
|
||||||
} else if ("\\Deleted".equals(flag)) {
|
|
||||||
message.deleted = true;
|
|
||||||
} else if ("\\Flagged".equals(flag)) {
|
|
||||||
properties.put("flagged", "2");
|
|
||||||
message.flagged = true;
|
|
||||||
} else if ("Junk".equals(flag)) {
|
|
||||||
properties.put("junk", "1");
|
|
||||||
message.junk = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (properties.size() > 0) {
|
|
||||||
session.updateMessage(messages.getByUid(uid), properties);
|
|
||||||
}
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (ExchangeSession.Message currentMessage : messages) {
|
for (ExchangeSession.Message currentMessage : messages) {
|
||||||
index++;
|
index++;
|
||||||
@ -387,6 +351,22 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
String folderName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
String folderName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
||||||
// TODO handle flags
|
// TODO handle flags
|
||||||
String flags = tokens.nextToken();
|
String flags = tokens.nextToken();
|
||||||
|
HashMap<String, String> properties = new HashMap<String, String>();
|
||||||
|
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
||||||
|
while (flagtokenizer.hasMoreTokens()) {
|
||||||
|
String flag = flagtokenizer.nextToken();
|
||||||
|
if ("\\Seen".equals(flag)) {
|
||||||
|
properties.put("read", "1");
|
||||||
|
} else if ("\\Flagged".equals(flag)) {
|
||||||
|
properties.put("flagged", "2");
|
||||||
|
} else if ("\\Answered".equals(flag)) {
|
||||||
|
properties.put("answered", "103");
|
||||||
|
} else if ("\\Draft".equals(flag)) {
|
||||||
|
properties.put("draft", "9");
|
||||||
|
} else if ("Junk".equals(flag)) {
|
||||||
|
properties.put("junk", "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
// skip optional date
|
// skip optional date
|
||||||
String dateOrSize = tokens.nextToken();
|
String dateOrSize = tokens.nextToken();
|
||||||
if (tokens.hasMoreTokens()) {
|
if (tokens.hasMoreTokens()) {
|
||||||
@ -407,7 +387,7 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
readClient();
|
readClient();
|
||||||
|
|
||||||
String messageName = UUID.randomUUID().toString();
|
String messageName = UUID.randomUUID().toString();
|
||||||
session.createMessage(session.getFolderPath(folderName), messageName, null, new String(buffer), false);
|
session.createMessage(session.getFolderPath(folderName), messageName, properties, new String(buffer), false);
|
||||||
sendClient(commandId + " OK APPEND completed");
|
sendClient(commandId + " OK APPEND completed");
|
||||||
} else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) {
|
} else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) {
|
||||||
if (currentFolder != null) {
|
if (currentFolder != null) {
|
||||||
@ -473,6 +453,49 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateFlags(ExchangeSession.Message message, String action, String flags) throws IOException {
|
||||||
|
HashMap<String, String> properties = new HashMap<String, String>();
|
||||||
|
if ("-Flags".equalsIgnoreCase(action)) {
|
||||||
|
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
||||||
|
while (flagtokenizer.hasMoreTokens()) {
|
||||||
|
String flag = flagtokenizer.nextToken();
|
||||||
|
if ("\\Seen".equals(flag)) {
|
||||||
|
properties.put("read", "0");
|
||||||
|
message.read = false;
|
||||||
|
} else if ("\\Flagged".equals(flag)) {
|
||||||
|
properties.put("flagged", "0");
|
||||||
|
message.flagged = false;
|
||||||
|
} else if ("Junk".equals(flag)) {
|
||||||
|
properties.put("junk", "0");
|
||||||
|
message.junk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("+Flags".equalsIgnoreCase(action)) {
|
||||||
|
StringTokenizer flagtokenizer = new StringTokenizer(flags);
|
||||||
|
while (flagtokenizer.hasMoreTokens()) {
|
||||||
|
String flag = flagtokenizer.nextToken();
|
||||||
|
if ("\\Seen".equals(flag)) {
|
||||||
|
properties.put("read", "1");
|
||||||
|
message.read = true;
|
||||||
|
} else if ("\\Deleted".equals(flag)) {
|
||||||
|
message.deleted = true;
|
||||||
|
} else if ("\\Flagged".equals(flag)) {
|
||||||
|
properties.put("flagged", "2");
|
||||||
|
message.flagged = true;
|
||||||
|
} else if ("\\Answered".equals(flag)) {
|
||||||
|
properties.put("answered", "103");
|
||||||
|
message.answered = true;
|
||||||
|
} else if ("Junk".equals(flag)) {
|
||||||
|
properties.put("junk", "1");
|
||||||
|
message.junk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (properties.size() > 0) {
|
||||||
|
session.updateMessage(message, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode IMAP credentials
|
* Decode IMAP credentials
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user