From 3418daed6548002ee78dd7871db95acfebb25b75 Mon Sep 17 00:00:00 2001 From: mguessan Date: Sat, 24 Jul 2010 10:54:27 +0000 Subject: [PATCH] Carddav: use new ExchangePropPatchMethod in full contact create/update git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1261 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../exchange/dav/DavExchangeSession.java | 10 ++-- .../exchange/dav/ExchangePropPatchMethod.java | 57 +++++++++++++------ src/java/davmail/exchange/dav/Field.java | 31 ++++++++++ .../davmail/exchange/dav/PropertyValue.java | 29 +++++----- 4 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java index d53bae79..13b04b92 100644 --- a/src/java/davmail/exchange/dav/DavExchangeSession.java +++ b/src/java/davmail/exchange/dav/DavExchangeSession.java @@ -596,12 +596,12 @@ public class DavExchangeSession extends ExchangeSession { super(folderPath, itemName, properties, etag, noneMatch); } - protected List buildProperties() { - ArrayList list = new ArrayList(); + protected Set buildProperties() { + Set list = new HashSet(); for (Map.Entry entry : entrySet()) { String key = entry.getKey(); if (!"photo".equals(key)) { - list.add(Field.createDavProperty(key, entry.getValue())); + list.add(Field.createPropertyValue(key, entry.getValue())); } } @@ -616,7 +616,7 @@ public class DavExchangeSession extends ExchangeSession { */ public ItemResult createOrUpdate() throws IOException { int status = 0; - PropPatchMethod propPatchMethod = new PropPatchMethod(URIUtil.encodePath(getHref()), buildProperties()) { + ExchangePropPatchMethod propPatchMethod = new ExchangePropPatchMethod(URIUtil.encodePath(getHref()), buildProperties()) { @Override protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) { // ignore response body, sometimes invalid with exchange mapi properties @@ -697,7 +697,7 @@ public class DavExchangeSession extends ExchangeSession { // update haspicture flag to boolean property DavPropertyName hasPicturePropertyName = Field.getPropertyName("haspicture"); Set propertyValues = new HashSet(); - propertyValues.add(new PropertyValue(hasPicturePropertyName.getNamespace(),hasPicturePropertyName.getName(),"1", PropertyType.Boolean)); + propertyValues.add(new PropertyValue(hasPicturePropertyName.getNamespace().getURI(),hasPicturePropertyName.getName(),"1", PropertyType.Boolean)); ExchangePropPatchMethod exchangePropPatchMethod = new ExchangePropPatchMethod(URIUtil.encodePath(getHref()), propertyValues); try { status = httpClient.executeMethod(exchangePropPatchMethod); diff --git a/src/java/davmail/exchange/dav/ExchangePropPatchMethod.java b/src/java/davmail/exchange/dav/ExchangePropPatchMethod.java index dc9ff796..fd1f6fbc 100644 --- a/src/java/davmail/exchange/dav/ExchangePropPatchMethod.java +++ b/src/java/davmail/exchange/dav/ExchangePropPatchMethod.java @@ -18,7 +18,6 @@ */ package davmail.exchange.dav; -import davmail.util.StringUtil; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.EntityEnclosingMethod; import org.apache.commons.httpclient.methods.RequestEntity; @@ -41,7 +40,7 @@ import java.util.*; public class ExchangePropPatchMethod extends EntityEnclosingMethod { protected static final Logger logger = Logger.getLogger(ExchangePropPatchMethod.class); - static final Namespace TYPE_NAMESPACE = Namespace.getNamespace("urn:schemas-microsoft-com:datatypes"); + static final String TYPE_NAMESPACE = "urn:schemas-microsoft-com:datatypes"; final Set propertyValues; /** @@ -84,7 +83,7 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { try { // build namespace map int currentChar = 'e'; - final Map nameSpaceMap = new HashMap(); + final Map nameSpaceMap = new HashMap(); final Set setPropertyValues = new HashSet(); final Set deletePropertyValues = new HashSet(); for (PropertyValue propertyValue : propertyValues) { @@ -93,11 +92,11 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { nameSpaceMap.put(TYPE_NAMESPACE, currentChar++); } // property namespace - Namespace namespace = propertyValue.getNamespace(); - if (!nameSpaceMap.containsKey(namespace)) { - nameSpaceMap.put(namespace, currentChar++); + String namespaceUri = propertyValue.getNamespaceUri(); + if (!nameSpaceMap.containsKey(namespaceUri)) { + nameSpaceMap.put(namespaceUri, currentChar++); } - if (propertyValue.getValue() == null) { + if (propertyValue.getXmlEncodedValue() == null) { deletePropertyValues.add(propertyValue); } else { setPropertyValues.add(propertyValue); @@ -106,11 +105,11 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(baos, "UTF-8"); writer.write(" mapEntry : nameSpaceMap.entrySet()) { + for (Map.Entry mapEntry : nameSpaceMap.entrySet()) { writer.write(" xmlns:"); writer.write((char) mapEntry.getValue().intValue()); writer.write("=\""); - writer.write(mapEntry.getKey().getURI()); + writer.write(mapEntry.getKey()); writer.write("\""); } writer.write(">"); @@ -118,7 +117,7 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { writer.write(""); for (PropertyValue propertyValue : setPropertyValues) { PropertyType propertyType = propertyValue.getType(); - char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespace()).intValue(); + char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespaceUri()).intValue(); writer.write('<'); writer.write(nameSpaceChar); writer.write(':'); @@ -131,7 +130,7 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { writer.write("\""); } writer.write('>'); - writer.write(StringUtil.xmlEncode(propertyValue.getValue())); + writer.write(propertyValue.getXmlEncodedValue()); writer.write(""); for (PropertyValue propertyValue : deletePropertyValues) { - char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespace()).intValue(); + char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespaceUri()).intValue(); writer.write('<'); writer.write(nameSpaceChar); writer.write(':'); @@ -220,18 +219,41 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { protected void handleResponse(XMLStreamReader reader) throws XMLStreamException { MultiStatusResponse multiStatusResponse = null; - int currentStatus = 0; + int status = 0; + String href = null; while (reader.hasNext() && !isEndTag(reader, "response")) { int event = reader.next(); if (event == XMLStreamConstants.START_ELEMENT) { String tagLocalName = reader.getLocalName(); if ("href".equals(tagLocalName)) { - multiStatusResponse = new MultiStatusResponse(reader.getElementText(), ""); + href = reader.getElementText(); } else if ("status".equals(tagLocalName)) { - if ("HTTP/1.1 200 OK".equals(reader.getElementText())) { - currentStatus = HttpStatus.SC_OK; + String responseStatus = reader.getElementText(); + if ("HTTP/1.1 200 OK".equals(responseStatus)) { + status = HttpStatus.SC_OK; + } else if ("HTTP/1.1 201 Created".equals(responseStatus)) { + status = HttpStatus.SC_CREATED; } - } else if ("prop".equals(tagLocalName) && currentStatus == HttpStatus.SC_OK) { + multiStatusResponse = new MultiStatusResponse(href, status); + } else if ("propstat".equals(tagLocalName)) { + handlePropstat(reader, multiStatusResponse); + } + } + } + + } + + protected void handlePropstat(XMLStreamReader reader, MultiStatusResponse multiStatusResponse) throws XMLStreamException { + int propstatStatus = 0; + while (reader.hasNext() && !isEndTag(reader, "propstat")) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + String tagLocalName = reader.getLocalName(); + if ("status".equals(tagLocalName)) { + if ("HTTP/1.1 200 OK".equals(reader.getElementText())) { + propstatStatus = HttpStatus.SC_OK; + } + } else if ("prop".equals(tagLocalName) && propstatStatus == HttpStatus.SC_OK) { handleProperty(reader, multiStatusResponse); } } @@ -239,6 +261,7 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod { } + protected void handleProperty(XMLStreamReader reader, MultiStatusResponse multiStatusResponse) throws XMLStreamException { while (reader.hasNext() && !isEndTag(reader, "prop")) { try { diff --git a/src/java/davmail/exchange/dav/Field.java b/src/java/davmail/exchange/dav/Field.java index 5355e2bb..0978e791 100644 --- a/src/java/davmail/exchange/dav/Field.java +++ b/src/java/davmail/exchange/dav/Field.java @@ -18,6 +18,7 @@ */ package davmail.exchange.dav; +import davmail.util.StringUtil; import org.apache.jackrabbit.webdav.DavConstants; import org.apache.jackrabbit.webdav.property.DavPropertyName; import org.apache.jackrabbit.webdav.property.DefaultDavProperty; @@ -477,6 +478,36 @@ public class Field { } } + public static PropertyValue createPropertyValue(String alias, String value) { + Field field = Field.get(alias); + String encodedValue = null; + DavPropertyName davPropertyName = field.davPropertyName; + if (value == null) { + // return DavPropertyName to remove property + return new PropertyValue(davPropertyName.getNamespace().getURI(), davPropertyName.getName()); + } else if (field.isMultivalued) { + StringBuilder buffer = new StringBuilder(); + // multivalued field, split values separated by \n + String[] values = value.split("\n"); + for (final String singleValue : values) { + buffer.append(""); + buffer.append(StringUtil.xmlEncode(singleValue)); + buffer.append(""); + } + return new PropertyValue(davPropertyName.getNamespace().getURI(), davPropertyName.getName(), buffer.toString()); + } else if (field.isBooleanValue) { + if ("true".equals(value)) { + return new PropertyValue(davPropertyName.getNamespace().getURI(), davPropertyName.getName(), "1"); + } else if ("false".equals(value)) { + return new PropertyValue(davPropertyName.getNamespace().getURI(), davPropertyName.getName(), "0"); + } else { + throw new RuntimeException("Invalid value for " + field.alias + ": " + value); + } + } else { + return new PropertyValue(davPropertyName.getNamespace().getURI(), davPropertyName.getName(), StringUtil.xmlEncode(value)); + } + } + /** * SEARCH request property name for alias * diff --git a/src/java/davmail/exchange/dav/PropertyValue.java b/src/java/davmail/exchange/dav/PropertyValue.java index 0f73fa8c..25113a64 100644 --- a/src/java/davmail/exchange/dav/PropertyValue.java +++ b/src/java/davmail/exchange/dav/PropertyValue.java @@ -18,39 +18,36 @@ */ package davmail.exchange.dav; -import org.apache.jackrabbit.webdav.xml.Namespace; - - /** * Property value. */ public class PropertyValue { - protected Namespace namespace; + protected String namespaceUri; protected String name; - protected String value; + protected String xmlEncodedValue; protected PropertyType type; - public PropertyValue(Namespace namespace, String name) { - this(namespace, name, null, null); + public PropertyValue(String namespaceUri, String name) { + this(namespaceUri, name, null, null); } - public PropertyValue(Namespace namespace, String name, String value) { - this(namespace, name, value, null); + public PropertyValue(String namespaceUri, String name, String xmlEncodedValue) { + this(namespaceUri, name, xmlEncodedValue, null); } - public PropertyValue(Namespace namespace, String name, String value, PropertyType type) { - this.namespace = namespace; + public PropertyValue(String namespaceUri, String name, String xmlEncodedValue, PropertyType type) { + this.namespaceUri = namespaceUri; this.name = name; - this.value = value; + this.xmlEncodedValue = xmlEncodedValue; this.type = type; } - public Namespace getNamespace() { - return namespace; + public String getNamespaceUri() { + return namespaceUri; } - public String getValue() { - return value; + public String getXmlEncodedValue() { + return xmlEncodedValue; } public PropertyType getType() {