diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 30eabdc9..ca6144f1 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -1593,7 +1593,7 @@ public abstract class ExchangeSession { public abstract static class Item extends HashMap { protected String folderPath; protected String itemName; - protected String permanentUrl; + public String permanentUrl; /** * Display name. */ @@ -1685,9 +1685,9 @@ public abstract class ExchangeSession { } /** - * Calendar event object + * Contact object */ - public abstract static class Contact extends Item { + public abstract class Contact extends Item { /** * @inheritDoc @@ -1791,6 +1791,15 @@ public abstract class ExchangeSession { writer.appendProperty("REV", get("lastmodified")); + if ("1".equals(get("haspicture"))) { + try { + ContactPhoto contactPhoto = getContactPhoto(this); + writer.appendProperty("PHOTO;TYPE=\"" + contactPhoto.type + "\";ENCODING=\"b\"", contactPhoto.content); + } catch (IOException e) { + LOGGER.warn("Unable to get photo from contact " + this.get("cn")); + } + } + writer.endCard(); return writer.toString(); } @@ -2549,6 +2558,20 @@ public abstract class ExchangeSession { */ public abstract Item getItem(String folderPath, String itemName) throws IOException; + public class ContactPhoto { + public String type; + public String content; + } + + /** + * Retrieve contact photo attached to contact + * @param contact address book contact + * @return contact photo + * @throws IOException on error + */ + public abstract ContactPhoto getContactPhoto(Contact contact) throws IOException; + + /** * Delete event named eventName in folder * @@ -2651,13 +2674,13 @@ public abstract class ExchangeSession { } else if ("NICKNAME".equals(property.getKey())) { properties.put("nickname", property.getValue()); } else if ("TEL".equals(property.getKey())) { - if (property.hasParam("TYPE", "cell")) { + if (property.hasParam("TYPE", "cell") || property.hasParam("X-GROUP", "CELL")) { properties.put("mobile", property.getValue()); } - if (property.hasParam("TYPE", "work")) { + if (property.hasParam("TYPE", "work") || property.hasParam("X-GROUP", "WORK")) { properties.put("telephoneNumber", property.getValue()); } - if (property.hasParam("TYPE", "home")) { + if (property.hasParam("TYPE", "home") || property.hasParam("X-GROUP", "HOME")) { properties.put("homePhone", property.getValue()); } if (property.hasParam("TYPE", "fax")) { @@ -3015,6 +3038,8 @@ public abstract class ExchangeSession { static { CONTACT_ATTRIBUTES.add("imapUid"); + CONTACT_ATTRIBUTES.add("etag"); + CONTACT_ATTRIBUTES.add("extensionattribute1"); CONTACT_ATTRIBUTES.add("extensionattribute2"); CONTACT_ATTRIBUTES.add("extensionattribute3"); @@ -3066,7 +3091,7 @@ public abstract class ExchangeSession { CONTACT_ATTRIBUTES.add("otherpostalcode"); CONTACT_ATTRIBUTES.add("othercountry"); CONTACT_ATTRIBUTES.add("othercity"); - + CONTACT_ATTRIBUTES.add("haspicture"); } /** diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java index e02bc27d..7f39ed68 100644 --- a/src/java/davmail/exchange/dav/DavExchangeSession.java +++ b/src/java/davmail/exchange/dav/DavExchangeSession.java @@ -43,7 +43,9 @@ import org.apache.jackrabbit.webdav.property.DavProperty; import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import org.apache.jackrabbit.webdav.property.DavPropertySet; +import javax.mail.BodyPart; import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimePart; @@ -1182,6 +1184,45 @@ public class DavExchangeSession extends ExchangeSession { return item; } + @Override + public ExchangeSession.ContactPhoto getContactPhoto(ExchangeSession.Contact contact) throws IOException { + ContactPhoto contactPhoto; + final GetMethod method = new GetMethod(URIUtil.encodePath(contact.permanentUrl)); + method.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); + method.setRequestHeader("Translate", "f"); + method.setRequestHeader("Accept-Encoding", "gzip"); + + try { + DavGatewayHttpClientFacade.executeGetMethod(httpClient, method, true); + InputStream inputStream; + if (isGzipEncoded(method)) { + inputStream = (new GZIPInputStream(method.getResponseBodyAsStream())); + } else { + inputStream = method.getResponseBodyAsStream(); + } + MimeMessage mimeMessage = new MimeMessage(null, inputStream); + BodyPart photoBodyPart = ((MimeMultipart) mimeMessage.getContent()).getBodyPart(1); + contactPhoto = new ContactPhoto(); + String contentType = photoBodyPart.getContentType(); + contactPhoto.type = contentType.substring(0, contentType.indexOf(';')); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream partInputStream = ((MimeBodyPart) photoBodyPart).getInputStream(); + byte[] bytes = new byte[8192]; + int length; + while ((length = partInputStream.read(bytes)) > 0) { + baos.write(bytes, 0, length); + } + contactPhoto.content = new String(Base64.encodeBase64(baos.toByteArray())); + } catch (MessagingException e) { + throw new IOException(e); + } finally { + method.releaseConnection(); + } + + return contactPhoto; + } + @Override public int sendEvent(String icsBody) throws IOException { String itemName = UUID.randomUUID().toString() + ".EML"; diff --git a/src/java/davmail/exchange/dav/Field.java b/src/java/davmail/exchange/dav/Field.java index 6e9ace2f..9200c95c 100644 --- a/src/java/davmail/exchange/dav/Field.java +++ b/src/java/davmail/exchange/dav/Field.java @@ -243,6 +243,8 @@ public class Field { createField("private", DistinguishedPropertySetType.Common, 0x8506, "private"); // True/False createField("sensitivity", 0x0036, PropertyType.Long); // PR_SENSITIVITY SENSITIVITY_PRIVATE=2, SENSITIVITY_NONE = 0 + createField("haspicture", DistinguishedPropertySetType.Address, 0x8015, "haspicture"); // True/False + // OWA settings createField("messageclass", 0x001a, PropertyType.String); createField("roamingxmlstream", 0x7c08, PropertyType.Binary);