From 144e86dc747254675e990b263d30a67eb7c667fe Mon Sep 17 00:00:00 2001 From: mguessan Date: Sun, 18 Jul 2010 22:54:54 +0000 Subject: [PATCH] Carddav: handle picture delete git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1195 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../davmail/exchange/ExchangeSession.java | 7 +- .../exchange/dav/DavExchangeSession.java | 72 ++++++++++------- src/java/davmail/exchange/dav/Field.java | 38 ++++----- .../exchange/TestExchangeSessionContact.java | 81 +++++++++++++++++++ 4 files changed, 145 insertions(+), 53 deletions(-) diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 60e943b3..ab8ac851 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -2813,14 +2813,15 @@ public abstract class ExchangeSession { properties.put("spousecn", property.getValue()); } else if ("PHOTO".equals(property.getKey())) { properties.put("photo", property.getValue()); + properties.put("haspicture", "true"); } } // reset missing properties to null for (String key : CONTACT_ATTRIBUTES) { - if (!"imapUid".equals(key) && !"etag".equals(key) && !"urlcompname".equals(key) && + if (!"imapUid".equals(key) && !"etag".equals(key) && !"urlcompname".equals(key) + && !"lastmodified".equals(key) && !properties.containsKey(key)) { -// TODO: enable - //properties.put(key, null); + properties.put(key, null); } } diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java index 2cf4912a..bca5054b 100644 --- a/src/java/davmail/exchange/dav/DavExchangeSession.java +++ b/src/java/davmail/exchange/dav/DavExchangeSession.java @@ -591,7 +591,7 @@ public class DavExchangeSession extends ExchangeSession { ArrayList list = new ArrayList(); for (Map.Entry entry : entrySet()) { String key = entry.getKey(); - if (key.startsWith("email") || "private".equals(key)) { + if (key.startsWith("email")) { list.add(Field.createDavProperty("write" + key, entry.getValue())); } else if (!"photo".equals(key)) { list.add(Field.createDavProperty(key, entry.getValue())); @@ -646,11 +646,10 @@ public class DavExchangeSession extends ExchangeSession { } itemResult.status = status; - + String contactPictureUrl = getHref() + "/ContactPicture.jpg"; String photo = get("photo"); if (photo != null) { // photo url - String contactPictureUrl = getHref() + "/ContactPicture.jpg"; // need to update photo BufferedImage image = ImageIO.read(new ByteArrayInputStream(Base64.decodeBase64(photo.getBytes()))); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -689,6 +688,20 @@ public class DavExchangeSession extends ExchangeSession { attachmentPropPatchMethod.releaseConnection(); } + } else { + // try to delete picture + DeleteMethod deleteMethod = new DeleteMethod(contactPictureUrl); + try { + status = httpClient.executeMethod(deleteMethod); + if (status != HttpStatus.SC_OK && status != HttpStatus.SC_NOT_FOUND) { + throw new IOException("Unable to delete contact picture"); + } + } catch (IOException e) { + LOGGER.error("Error in contact photo delete", e); + throw e; + } finally { + deleteMethod.releaseConnection(); + } } // need to retrieve new etag HeadMethod headMethod = new HeadMethod(URIUtil.encodePath(getHref())); @@ -1209,35 +1222,36 @@ public class DavExchangeSession extends ExchangeSession { @Override public ExchangeSession.ContactPhoto getContactPhoto(ExchangeSession.Contact contact) throws IOException { - ContactPhoto contactPhoto; - final GetMethod method = new GetMethod(contact.getHref() + "/ContactPicture.jpg"); - method.setRequestHeader("Translate", "f"); - method.setRequestHeader("Accept-Encoding", "gzip"); + ContactPhoto contactPhoto = null; + if ("1".equals(contact.get("haspicture"))) { + final GetMethod method = new GetMethod(contact.getHref() + "/ContactPicture.jpg"); + 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(); + try { + DavGatewayHttpClientFacade.executeGetMethod(httpClient, method, true); + InputStream inputStream; + if (isGzipEncoded(method)) { + inputStream = (new GZIPInputStream(method.getResponseBodyAsStream())); + } else { + inputStream = method.getResponseBodyAsStream(); + } + + contactPhoto = new ContactPhoto(); + contactPhoto.contentType = "image/jpeg"; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream partInputStream = inputStream; + 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())); + } finally { + method.releaseConnection(); } - - contactPhoto = new ContactPhoto(); - contactPhoto.contentType = "image/jpeg"; - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - InputStream partInputStream = inputStream; - 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())); - } finally { - method.releaseConnection(); } - return contactPhoto; } diff --git a/src/java/davmail/exchange/dav/Field.java b/src/java/davmail/exchange/dav/Field.java index b543bdef..0dd6ad52 100644 --- a/src/java/davmail/exchange/dav/Field.java +++ b/src/java/davmail/exchange/dav/Field.java @@ -132,8 +132,7 @@ public class Field { createField("iconIndex", 0x1080, PropertyType.Long);//PR_ICON_INDEX createField(URN_SCHEMAS_HTTPMAIL, "read"); //createField("read", 0x0e69, PropertyType.Boolean);//PR_READ - createField("deleted", DistinguishedPropertySetType.Common, 0x8570, "deleted"); - createField("writedeleted", DistinguishedPropertySetType.Common, 0x8570, PropertyType.String10); + createField("deleted", DistinguishedPropertySetType.Common, 0x8570, "deleted", PropertyType.Boolean); createField(URN_SCHEMAS_HTTPMAIL, "date");//PR_CLIENT_SUBMIT_TIME, 0x0039 //createField("date", 0x0e06, PropertyType.SystemTime);//PR_MESSAGE_DELIVERY_TIME @@ -251,10 +250,9 @@ public class Field { // contact private flags createField("private", DistinguishedPropertySetType.Common, 0x8506, "private", PropertyType.Boolean); // True/False - createField("writeprivate", DistinguishedPropertySetType.Common, 0x8506, PropertyType.Boolean); createField("sensitivity", 0x0036, PropertyType.Long); // PR_SENSITIVITY SENSITIVITY_PRIVATE = 2, SENSITIVITY_PERSONAL = 1, SENSITIVITY_NONE = 0 - createField("haspicture", DistinguishedPropertySetType.Address, 0x8015, "haspicture"); // True/False + createField("haspicture", DistinguishedPropertySetType.Address, 0x8015, "haspicture", PropertyType.Boolean); // True/False // OWA settings createField("messageclass", 0x001a, PropertyType.String); @@ -279,7 +277,7 @@ public class Field { String name = 'x' + toHexString(propertyTag) + propertyTypeMap.get(propertyType); Field field; if (propertyType == PropertyType.Binary) { - field = new Field(alias, SCHEMAS_MAPI_PROPTAG, name, null, "bin.base64", propertyType); + field = new Field(alias, SCHEMAS_MAPI_PROPTAG, name, null, "bin.base64", name, propertyType); } else { field = new Field(alias, SCHEMAS_MAPI_PROPTAG, name, propertyType); } @@ -292,6 +290,7 @@ public class Field { protected static void createField(String alias, DistinguishedPropertySetType propertySetType, int propertyTag, String responseAlias, PropertyType propertyType) { String name; + String updateAlias; if (propertySetType == DistinguishedPropertySetType.Address) { // Address namespace expects integer names name = String.valueOf(propertyTag); @@ -299,16 +298,9 @@ public class Field { // Common namespace expects hex names name = "0x" + toHexString(propertyTag); } + updateAlias = "_x0030_x" + toHexString(propertyTag); Field field = new Field(alias, Namespace.getNamespace(SCHEMAS_MAPI_ID.getURI() + - '{' + distinguishedPropertySetMap.get(propertySetType) + "}/"), name, responseAlias, null, propertyType); - fieldMap.put(field.alias, field); - } - - protected static void createField(String alias, DistinguishedPropertySetType propertySetType, int propertyTag, PropertyType propertyType) { - String name = "_x0030_x" + toHexString(propertyTag); - - Field field = new Field(alias, Namespace.getNamespace(SCHEMAS_MAPI_ID.getURI() + - '{' + distinguishedPropertySetMap.get(propertySetType) + "}/"), name, propertyType); + '{' + distinguishedPropertySetMap.get(propertySetType) + "}/"), name, responseAlias, null, updateAlias, propertyType); fieldMap.put(field.alias, field); } @@ -333,6 +325,7 @@ public class Field { protected final String uri; protected final String requestPropertyString; protected final DavPropertyName responsePropertyName; + protected final DavPropertyName updatePropertyName; protected final String cast; protected final boolean isIntValue; protected final boolean isMultivalued; @@ -344,11 +337,12 @@ public class Field { } public Field(String alias, Namespace namespace, String name, PropertyType propertyType) { - this(alias, namespace, name, null, null, propertyType); + this(alias, namespace, name, null, null, name, propertyType); } - public Field(String alias, Namespace namespace, String name, String responseAlias, String cast, PropertyType propertyType) { + public Field(String alias, Namespace namespace, String name, String responseAlias, String cast, String updateAlias, PropertyType propertyType) { davPropertyName = DavPropertyName.create(name, namespace); + updatePropertyName = DavPropertyName.create(updateAlias, namespace); this.propertyType = propertyType; isMultivalued = propertyType == PropertyType.StringArray; isIntValue = propertyType == PropertyType.Integer || propertyType == PropertyType.Long; @@ -405,7 +399,7 @@ public class Field { Field field = Field.get(alias); if (value == null) { // return DavPropertyName to remove property - return field.davPropertyName; + return field.updatePropertyName; } else if (field.isMultivalued) { List valueList = new ArrayList(); String[] values = value.split("\n"); @@ -417,15 +411,17 @@ public class Field { }); } - return new DefaultDavProperty(field.davPropertyName, valueList); + return new DefaultDavProperty(field.updatePropertyName, valueList); } else if (field.isBooleanValue) { if ("true".equals(value)) { - return new DefaultDavProperty(field.davPropertyName, "1"); + return new DefaultDavProperty(field.updatePropertyName, "1"); + } else if ("false".equals(value)){ + return new DefaultDavProperty(field.updatePropertyName, "0"); } else { - return new DefaultDavProperty(field.davPropertyName, "0"); + throw new RuntimeException("Invalid value for "+field.alias+": "+value); } } else { - return new DefaultDavProperty(field.davPropertyName, value); + return new DefaultDavProperty(field.updatePropertyName, value); } } diff --git a/src/test/davmail/exchange/TestExchangeSessionContact.java b/src/test/davmail/exchange/TestExchangeSessionContact.java index 63244476..f5f0245b 100644 --- a/src/test/davmail/exchange/TestExchangeSessionContact.java +++ b/src/test/davmail/exchange/TestExchangeSessionContact.java @@ -193,4 +193,85 @@ public class TestExchangeSessionContact extends AbstractExchangeSessionTestCase assertNotNull(session.getContactPhoto(contact)); } + + public void testUpdateContact() throws IOException { + ExchangeSession.Contact contact = (ExchangeSession.Contact) session.getItem("testcontactfolder", itemName); + + VCardWriter vCardWriter = new VCardWriter(); + vCardWriter.startCard(); + + vCardWriter.endCard(); + + ExchangeSession.ItemResult result = session.createOrUpdateContact("testcontactfolder", itemName, vCardWriter.toString(), contact.etag, null); + assertEquals(200, result.status); + + contact = (ExchangeSession.Contact) session.getItem("testcontactfolder", itemName); + assertNull(contact.get("cn")); + assertNull(contact.get("sn")); + assertNull(contact.get("givenName")); + assertNull(contact.get("middlename")); + assertNull(contact.get("personaltitle")); + assertNull(contact.get("namesuffix")); + assertNotNull("lastmodified"); + assertNull(contact.get("nickname")); + + assertNull(contact.get("mobile")); + assertNull(contact.get("telephoneNumber")); + assertNull(contact.get("homePhone")); + assertNull(contact.get("facsimiletelephonenumber")); + assertNull(contact.get("pager")); + + assertNull(contact.get("homepostofficebox")); + assertNull(contact.get("homeStreet")); + assertNull(contact.get("homeCity")); + assertNull(contact.get("homeState")); + assertNull(contact.get("homePostalCode")); + assertNull(contact.get("homeCountry")); + + assertNull(contact.get("postofficebox")); + assertNull(contact.get("roomnumber")); + assertNull(contact.get("street")); + assertNull(contact.get("l")); + assertNull(contact.get("st")); + assertNull(contact.get("postalcode")); + assertNull(contact.get("co")); + + assertNull(contact.get("email1")); + assertNull(contact.get("email2")); + assertNull(contact.get("email3")); + + assertNull(contact.get("o")); + assertNull(contact.get("department")); + + assertNull(contact.get("businesshomepage")); + assertNull(contact.get("title")); + assertNull(contact.get("description")); + + assertNull(contact.get("extensionattribute1")); + assertNull(contact.get("extensionattribute2")); + assertNull(contact.get("extensionattribute3")); + assertNull(contact.get("extensionattribute4")); + + assertNull(contact.get("profession")); + assertNull(contact.get("im")); + assertNull(contact.get("bday")); + + assertNull(contact.get("otherpostofficebox")); + assertNull(contact.get("otherstreet")); + assertNull(contact.get("othercity")); + assertNull(contact.get("otherstate")); + assertNull(contact.get("otherpostalcode")); + assertNull(contact.get("othercountry")); + + assertNull(contact.get("secretarycn")); + assertNull(contact.get("manager")); + assertNull(contact.get("spousecn")); + assertNull(contact.get("keywords")); + + assertNull(contact.get("private")); + + assertNull(session.getContactPhoto(contact)); + + + } }