mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 11:12:22 -05:00
Carddav: fix email address handling over EWS
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1467 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
919fde19e4
commit
b418fcbc06
@ -633,6 +633,10 @@ public abstract class ExchangeSession {
|
|||||||
*/
|
*/
|
||||||
public abstract MessageList searchMessages(String folderName, Set<String> attributes, Condition condition) throws IOException;
|
public abstract MessageList searchMessages(String folderName, Set<String> attributes, Condition condition) throws IOException;
|
||||||
|
|
||||||
|
public String getServerVersion() {
|
||||||
|
return serverVersion;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"JavaDoc"})
|
@SuppressWarnings({"JavaDoc"})
|
||||||
public enum Operator {
|
public enum Operator {
|
||||||
Or, And, Not, IsEqualTo,
|
Or, And, Not, IsEqualTo,
|
||||||
|
@ -469,9 +469,9 @@ public class VCalendar extends VObject {
|
|||||||
* VCalendar recipients for notifications
|
* VCalendar recipients for notifications
|
||||||
*/
|
*/
|
||||||
public static class Recipients {
|
public static class Recipients {
|
||||||
String attendees;
|
public String attendees;
|
||||||
String optionalAttendees;
|
public String optionalAttendees;
|
||||||
String organizer;
|
public String organizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -677,6 +677,8 @@ public abstract class EWSMethod extends PostMethod {
|
|||||||
handleMimeContent(reader, responseItem);
|
handleMimeContent(reader, responseItem);
|
||||||
} else if ("Attachments".equals(tagLocalName)) {
|
} else if ("Attachments".equals(tagLocalName)) {
|
||||||
responseItem.attachments = handleAttachments(reader);
|
responseItem.attachments = handleAttachments(reader);
|
||||||
|
} else if ("EmailAddresses".equals(tagLocalName)) {
|
||||||
|
handleEmailAddresses(reader, responseItem);
|
||||||
} else {
|
} else {
|
||||||
if (tagLocalName.endsWith("Id")) {
|
if (tagLocalName.endsWith("Id")) {
|
||||||
value = getAttributeValue(reader, "Id");
|
value = getAttributeValue(reader, "Id");
|
||||||
@ -695,6 +697,18 @@ public abstract class EWSMethod extends PostMethod {
|
|||||||
return responseItem;
|
return responseItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void handleEmailAddresses(XMLStreamReader reader, Item item) throws XMLStreamException {
|
||||||
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "EmailAddresses"))) {
|
||||||
|
reader.next();
|
||||||
|
if (XMLStreamUtil.isStartTag(reader)) {
|
||||||
|
String tagLocalName = reader.getLocalName();
|
||||||
|
if ("Entry".equals(tagLocalName)) {
|
||||||
|
item.put(reader.getAttributeValue(null, "Key"), reader.getElementText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected List<FileAttachment> handleAttachments(XMLStreamReader reader) throws XMLStreamException {
|
protected List<FileAttachment> handleAttachments(XMLStreamReader reader) throws XMLStreamException {
|
||||||
List<FileAttachment> attachments = new ArrayList<FileAttachment>();
|
List<FileAttachment> attachments = new ArrayList<FileAttachment>();
|
||||||
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Attachments"))) {
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Attachments"))) {
|
||||||
|
@ -898,16 +898,27 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
protected Contact() {
|
protected Contact() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<FieldUpdate> buildProperties() {
|
protected void buildProperties(List<FieldUpdate> updates) {
|
||||||
ArrayList<FieldUpdate> list = new ArrayList<FieldUpdate>();
|
|
||||||
for (Map.Entry<String, String> entry : entrySet()) {
|
for (Map.Entry<String, String> entry : entrySet()) {
|
||||||
if ("photo".equals(entry.getKey())) {
|
if ("photo".equals(entry.getKey())) {
|
||||||
list.add(Field.createFieldUpdate("haspicture", "true"));
|
updates.add(Field.createFieldUpdate("haspicture", "true"));
|
||||||
} else if (!entry.getKey().startsWith("email")) {
|
} else if (!entry.getKey().startsWith("email") && !entry.getKey().startsWith("smtpemail")) {
|
||||||
list.add(Field.createFieldUpdate(entry.getKey(), entry.getValue()));
|
updates.add(Field.createFieldUpdate(entry.getKey(), entry.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
// handle email addresses
|
||||||
|
IndexedFieldUpdate emailFieldUpdate = null;
|
||||||
|
for (Map.Entry<String, String> entry : entrySet()) {
|
||||||
|
if (entry.getKey().startsWith("smtpemail")) {
|
||||||
|
if (emailFieldUpdate == null) {
|
||||||
|
emailFieldUpdate = new IndexedFieldUpdate("EmailAddresses");
|
||||||
|
}
|
||||||
|
emailFieldUpdate.addFieldValue(Field.createFieldUpdate(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (emailFieldUpdate != null) {
|
||||||
|
updates.add(emailFieldUpdate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -955,8 +966,9 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FieldUpdate> properties = buildProperties();
|
List<FieldUpdate> properties = new ArrayList<FieldUpdate>();
|
||||||
if (currentItemId != null) {
|
if (currentItemId != null) {
|
||||||
|
buildProperties(properties);
|
||||||
// update
|
// update
|
||||||
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
|
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
|
||||||
ConflictResolution.AlwaysOverwrite,
|
ConflictResolution.AlwaysOverwrite,
|
||||||
@ -968,6 +980,7 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
newItem.type = "Contact";
|
newItem.type = "Contact";
|
||||||
// force urlcompname on create
|
// force urlcompname on create
|
||||||
properties.add(Field.createFieldUpdate("urlcompname", convertItemNameToEML(itemName)));
|
properties.add(Field.createFieldUpdate("urlcompname", convertItemNameToEML(itemName)));
|
||||||
|
buildProperties(properties);
|
||||||
newItem.setFieldUpdates(properties);
|
newItem.setFieldUpdates(properties);
|
||||||
createOrUpdateItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), newItem);
|
createOrUpdateItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), newItem);
|
||||||
}
|
}
|
||||||
@ -1103,12 +1116,26 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
} else {
|
} else {
|
||||||
updates.add(Field.createFieldUpdate("apptstateflags", "0"));
|
updates.add(Field.createFieldUpdate("apptstateflags", "0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vCalendar.isMeeting()) {
|
||||||
|
VCalendar.Recipients recipients = vCalendar.getRecipients(false);
|
||||||
|
if (recipients.attendees != null) {
|
||||||
|
updates.add(Field.createFieldUpdate("to", recipients.attendees));
|
||||||
|
}
|
||||||
|
if (recipients.optionalAttendees != null) {
|
||||||
|
updates.add(Field.createFieldUpdate("cc", recipients.optionalAttendees));
|
||||||
|
}
|
||||||
|
if (recipients.organizer != null && !vCalendar.isMeetingOrganizer()) {
|
||||||
|
updates.add(Field.createFieldUpdate("from", recipients.optionalAttendees));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// patch allday date values
|
// patch allday date values
|
||||||
if (vCalendar.isCdoAllDay()) {
|
if (vCalendar.isCdoAllDay()) {
|
||||||
updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
|
updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
|
||||||
updates.add(Field.createFieldUpdate("dtend", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTEND"))));
|
updates.add(Field.createFieldUpdate("dtend", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTEND"))));
|
||||||
}
|
}
|
||||||
updates.add(Field.createFieldUpdate("busystatus", "BUSY".equals(vCalendar.getFirstVeventPropertyValue("X-MICROSOFT-CDO-BUSYSTATUS"))?"Busy":"Free"));
|
updates.add(Field.createFieldUpdate("busystatus", "BUSY".equals(vCalendar.getFirstVeventPropertyValue("X-MICROSOFT-CDO-BUSYSTATUS")) ? "Busy" : "Free"));
|
||||||
if (vCalendar.isCdoAllDay()) {
|
if (vCalendar.isCdoAllDay()) {
|
||||||
if ("Exchange2010".equals(serverVersion)) {
|
if ("Exchange2010".equals(serverVersion)) {
|
||||||
updates.add(Field.createFieldUpdate("starttimezone", vCalendar.getVTimezone().getPropertyValue("TZID")));
|
updates.add(Field.createFieldUpdate("starttimezone", vCalendar.getVTimezone().getPropertyValue("TZID")));
|
||||||
|
@ -71,6 +71,10 @@ public class Field {
|
|||||||
FIELD_MAP.put("datereceived", new ExtendedFieldURI(0x0e06, ExtendedFieldURI.PropertyType.SystemTime));// PR_MESSAGE_DELIVERY_TIME
|
FIELD_MAP.put("datereceived", new ExtendedFieldURI(0x0e06, ExtendedFieldURI.PropertyType.SystemTime));// PR_MESSAGE_DELIVERY_TIME
|
||||||
FIELD_MAP.put("bcc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "bcc"));
|
FIELD_MAP.put("bcc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "bcc"));
|
||||||
|
|
||||||
|
FIELD_MAP.put("to", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "to"));
|
||||||
|
FIELD_MAP.put("cc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "cc"));
|
||||||
|
FIELD_MAP.put("from", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "from"));
|
||||||
|
|
||||||
// folder
|
// folder
|
||||||
FIELD_MAP.put("folderclass", new ExtendedFieldURI(0x3613, ExtendedFieldURI.PropertyType.String));
|
FIELD_MAP.put("folderclass", new ExtendedFieldURI(0x3613, ExtendedFieldURI.PropertyType.String));
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ import java.io.Writer;
|
|||||||
* Field update
|
* Field update
|
||||||
*/
|
*/
|
||||||
public class FieldUpdate {
|
public class FieldUpdate {
|
||||||
final FieldURI fieldURI;
|
FieldURI fieldURI;
|
||||||
final String value;
|
String value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create field update with value.
|
* Create field update with value.
|
||||||
@ -39,6 +39,10 @@ public class FieldUpdate {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected FieldUpdate() {
|
||||||
|
// empty constructor for subclass
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write field to request writer.
|
* Write field to request writer.
|
||||||
*
|
*
|
||||||
|
@ -45,31 +45,9 @@ public class IndexedFieldURI implements FieldURI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void appendValue(StringBuilder buffer, String itemType, String value) {
|
public void appendValue(StringBuilder buffer, String itemType, String value) {
|
||||||
if (fieldURI.startsWith("message")) {
|
buffer.append("<t:Entry Key=\"").append(fieldIndex).append("\">");
|
||||||
itemType = "Message";
|
buffer.append(StringUtil.xmlEncode(value));
|
||||||
} else if (fieldURI.startsWith("contacts")) {
|
buffer.append("</t:Entry>");
|
||||||
itemType = "Contact";
|
|
||||||
}
|
|
||||||
appendTo(buffer);
|
|
||||||
buffer.append("<t:");
|
|
||||||
buffer.append(itemType);
|
|
||||||
buffer.append('>');
|
|
||||||
if (fieldURI.endsWith("EmailAddress")) {
|
|
||||||
buffer.append("<t:EmailAddresses><t:Entry Key=\"").append(fieldIndex).append("\">");
|
|
||||||
buffer.append(StringUtil.xmlEncode(value));
|
|
||||||
buffer.append("</t:Entry></t:EmailAddresses>");
|
|
||||||
} else {
|
|
||||||
buffer.append("<t:");
|
|
||||||
buffer.append(fieldIndex);
|
|
||||||
buffer.append('>');
|
|
||||||
buffer.append(StringUtil.xmlEncode(value));
|
|
||||||
buffer.append("</t:");
|
|
||||||
buffer.append(fieldIndex);
|
|
||||||
buffer.append('>');
|
|
||||||
}
|
|
||||||
buffer.append("</t:");
|
|
||||||
buffer.append(itemType);
|
|
||||||
buffer.append('>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResponseName() {
|
public String getResponseName() {
|
||||||
|
73
src/java/davmail/exchange/ews/IndexedFieldUpdate.java
Normal file
73
src/java/davmail/exchange/ews/IndexedFieldUpdate.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
|
||||||
|
* Copyright (C) 2010 Mickael Guessant
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
package davmail.exchange.ews;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field update with multiple values.
|
||||||
|
*/
|
||||||
|
public class IndexedFieldUpdate extends FieldUpdate {
|
||||||
|
Set<FieldUpdate> updates = new HashSet<FieldUpdate>();
|
||||||
|
protected String collectionName;
|
||||||
|
|
||||||
|
public IndexedFieldUpdate(String collectionName) {
|
||||||
|
this.collectionName = collectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFieldValue(FieldUpdate fieldUpdate) {
|
||||||
|
updates.add(fieldUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write field to request writer.
|
||||||
|
*
|
||||||
|
* @param itemType item type
|
||||||
|
* @param writer request writer
|
||||||
|
* @throws IOException on error
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(String itemType, Writer writer) throws IOException {
|
||||||
|
if (itemType == null) {
|
||||||
|
// use collection name on create
|
||||||
|
writer.write("<t:");
|
||||||
|
writer.write(collectionName);
|
||||||
|
writer.write(">");
|
||||||
|
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
for (FieldUpdate fieldUpdate : updates) {
|
||||||
|
fieldUpdate.fieldURI.appendValue(buffer, itemType, fieldUpdate.value);
|
||||||
|
}
|
||||||
|
writer.write(buffer.toString());
|
||||||
|
|
||||||
|
writer.write("</t:");
|
||||||
|
writer.write(collectionName);
|
||||||
|
writer.write(">");
|
||||||
|
} else {
|
||||||
|
// on update, write each fieldupdate
|
||||||
|
for (FieldUpdate fieldUpdate : updates) {
|
||||||
|
fieldUpdate.write(itemType, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
|
|
||||||
* Copyright (C) 2010 Mickael Guessant
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
package davmail.exchange.ews;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internet Message Header Field.
|
|
||||||
*/
|
|
||||||
public class InternetMessageHeaderFieldURI extends IndexedFieldURI {
|
|
||||||
/**
|
|
||||||
* Create header field for field name.
|
|
||||||
*
|
|
||||||
* @param fieldName header field name
|
|
||||||
*/
|
|
||||||
public InternetMessageHeaderFieldURI(String fieldName) {
|
|
||||||
super("item:InternetMessageHeader", fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -267,6 +267,12 @@ public final class StringUtil {
|
|||||||
if (result.indexOf(':') >= 0) {
|
if (result.indexOf(':') >= 0) {
|
||||||
result = COLON_PATTERN.matcher(result).replaceAll("%3A");
|
result = COLON_PATTERN.matcher(result).replaceAll("%3A");
|
||||||
}
|
}
|
||||||
|
if (result.indexOf('<') >= 0) {
|
||||||
|
result = LT_PATTERN.matcher(result).replaceAll("%3C");
|
||||||
|
}
|
||||||
|
if (result.indexOf('>') >= 0) {
|
||||||
|
result = GT_PATTERN.matcher(result).replaceAll("%3E");
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package davmail.exchange;
|
package davmail.exchange;
|
||||||
|
|
||||||
|
import davmail.Settings;
|
||||||
import davmail.util.IOUtil;
|
import davmail.util.IOUtil;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
@ -179,7 +180,9 @@ public class TestExchangeSessionContact extends AbstractExchangeSessionTestCase
|
|||||||
assertEquals("http://fburl", contact.get("fburl"));
|
assertEquals("http://fburl", contact.get("fburl"));
|
||||||
|
|
||||||
assertEquals("true", contact.get("haspicture"));
|
assertEquals("true", contact.get("haspicture"));
|
||||||
assertNotNull(session.getContactPhoto(contact));
|
if (!Settings.getBooleanProperty("davmail.enableEws") || "Exchange2010".equals(session.getServerVersion())) {
|
||||||
|
assertNotNull(session.getContactPhoto(contact));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdateContact() throws IOException {
|
public void testUpdateContact() throws IOException {
|
||||||
|
Loading…
Reference in New Issue
Block a user