1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-12-13 03:02: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:
mguessan 2010-09-21 13:12:19 +00:00
parent 919fde19e4
commit b418fcbc06
11 changed files with 152 additions and 72 deletions

View File

@ -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,

View File

@ -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;
}
/**

View File

@ -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"))) {

View File

@ -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")));

View File

@ -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));

View File

@ -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.
*

View File

@ -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(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 Key=\"").append(fieldIndex).append("\">");
buffer.append(StringUtil.xmlEncode(value));
buffer.append("</t:Entry>");
}
public String getResponseName() {

View 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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -18,6 +18,7 @@
*/
package davmail.exchange;
import davmail.Settings;
import davmail.util.IOUtil;
import org.apache.commons.codec.binary.Base64;
@ -179,7 +180,9 @@ public class TestExchangeSessionContact extends AbstractExchangeSessionTestCase
assertEquals("http://fburl", contact.get("fburl"));
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 {