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 String getServerVersion() {
|
||||
return serverVersion;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"JavaDoc"})
|
||||
public enum Operator {
|
||||
Or, And, Not, IsEqualTo,
|
||||
|
@ -469,9 +469,9 @@ public class VCalendar extends VObject {
|
||||
* VCalendar recipients for notifications
|
||||
*/
|
||||
public static class Recipients {
|
||||
String attendees;
|
||||
String optionalAttendees;
|
||||
String organizer;
|
||||
public String attendees;
|
||||
public String optionalAttendees;
|
||||
public String organizer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -677,6 +677,8 @@ public abstract class EWSMethod extends PostMethod {
|
||||
handleMimeContent(reader, responseItem);
|
||||
} else if ("Attachments".equals(tagLocalName)) {
|
||||
responseItem.attachments = handleAttachments(reader);
|
||||
} else if ("EmailAddresses".equals(tagLocalName)) {
|
||||
handleEmailAddresses(reader, responseItem);
|
||||
} else {
|
||||
if (tagLocalName.endsWith("Id")) {
|
||||
value = getAttributeValue(reader, "Id");
|
||||
@ -695,6 +697,18 @@ public abstract class EWSMethod extends PostMethod {
|
||||
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 {
|
||||
List<FileAttachment> attachments = new ArrayList<FileAttachment>();
|
||||
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Attachments"))) {
|
||||
|
@ -898,16 +898,27 @@ public class EwsExchangeSession extends ExchangeSession {
|
||||
protected Contact() {
|
||||
}
|
||||
|
||||
protected List<FieldUpdate> buildProperties() {
|
||||
ArrayList<FieldUpdate> list = new ArrayList<FieldUpdate>();
|
||||
protected void buildProperties(List<FieldUpdate> updates) {
|
||||
for (Map.Entry<String, String> entry : entrySet()) {
|
||||
if ("photo".equals(entry.getKey())) {
|
||||
list.add(Field.createFieldUpdate("haspicture", "true"));
|
||||
} else if (!entry.getKey().startsWith("email")) {
|
||||
list.add(Field.createFieldUpdate(entry.getKey(), entry.getValue()));
|
||||
updates.add(Field.createFieldUpdate("haspicture", "true"));
|
||||
} else if (!entry.getKey().startsWith("email") && !entry.getKey().startsWith("smtpemail")) {
|
||||
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) {
|
||||
buildProperties(properties);
|
||||
// update
|
||||
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
|
||||
ConflictResolution.AlwaysOverwrite,
|
||||
@ -968,6 +980,7 @@ public class EwsExchangeSession extends ExchangeSession {
|
||||
newItem.type = "Contact";
|
||||
// force urlcompname on create
|
||||
properties.add(Field.createFieldUpdate("urlcompname", convertItemNameToEML(itemName)));
|
||||
buildProperties(properties);
|
||||
newItem.setFieldUpdates(properties);
|
||||
createOrUpdateItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), newItem);
|
||||
}
|
||||
@ -1103,12 +1116,26 @@ public class EwsExchangeSession extends ExchangeSession {
|
||||
} else {
|
||||
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
|
||||
if (vCalendar.isCdoAllDay()) {
|
||||
updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
|
||||
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 ("Exchange2010".equals(serverVersion)) {
|
||||
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("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
|
||||
FIELD_MAP.put("folderclass", new ExtendedFieldURI(0x3613, ExtendedFieldURI.PropertyType.String));
|
||||
|
||||
|
@ -25,8 +25,8 @@ import java.io.Writer;
|
||||
* Field update
|
||||
*/
|
||||
public class FieldUpdate {
|
||||
final FieldURI fieldURI;
|
||||
final String value;
|
||||
FieldURI fieldURI;
|
||||
String value;
|
||||
|
||||
/**
|
||||
* Create field update with value.
|
||||
@ -39,6 +39,10 @@ public class FieldUpdate {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
protected FieldUpdate() {
|
||||
// empty constructor for subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Write field to request writer.
|
||||
*
|
||||
|
@ -45,31 +45,9 @@ public class IndexedFieldURI implements FieldURI {
|
||||
}
|
||||
|
||||
public void appendValue(StringBuilder buffer, String itemType, String value) {
|
||||
if (fieldURI.startsWith("message")) {
|
||||
itemType = "Message";
|
||||
} else if (fieldURI.startsWith("contacts")) {
|
||||
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("<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('>');
|
||||
buffer.append("</t:Entry>");
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package davmail.exchange;
|
||||
|
||||
import davmail.Settings;
|
||||
import davmail.util.IOUtil;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
@ -179,8 +180,10 @@ public class TestExchangeSessionContact extends AbstractExchangeSessionTestCase
|
||||
assertEquals("http://fburl", contact.get("fburl"));
|
||||
|
||||
assertEquals("true", contact.get("haspicture"));
|
||||
if (!Settings.getBooleanProperty("davmail.enableEws") || "Exchange2010".equals(session.getServerVersion())) {
|
||||
assertNotNull(session.getContactPhoto(contact));
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateContact() throws IOException {
|
||||
ExchangeSession.Contact contact = getCurrentContact();
|
||||
|
Loading…
Reference in New Issue
Block a user