diff --git a/libs/ez-vcard-0.9.3.jar b/libs/ez-vcard-0.9.3.jar deleted file mode 100644 index a725ed10..00000000 Binary files a/libs/ez-vcard-0.9.3.jar and /dev/null differ diff --git a/libs/ez-vcard-0.9.5.jar b/libs/ez-vcard-0.9.5.jar new file mode 100644 index 00000000..2ad7bf2e Binary files /dev/null and b/libs/ez-vcard-0.9.5.jar differ diff --git a/src/at/bitfire/davdroid/resource/Contact.java b/src/at/bitfire/davdroid/resource/Contact.java index 17ca12cf..a1805ff1 100644 --- a/src/at/bitfire/davdroid/resource/Contact.java +++ b/src/at/bitfire/davdroid/resource/Contact.java @@ -24,7 +24,6 @@ import android.util.Log; import at.bitfire.davdroid.Constants; import ezvcard.Ezvcard; import ezvcard.VCard; -import ezvcard.VCardException; import ezvcard.VCardVersion; import ezvcard.ValidationWarnings; import ezvcard.parameter.EmailType; @@ -127,7 +126,7 @@ public class Contact extends Resource { /* VCard methods */ @Override - public void parseEntity(InputStream is) throws IOException, VCardException { + public void parseEntity(InputStream is) throws IOException { VCard vcard = Ezvcard.parse(is).first(); if (vcard == null) return; @@ -389,7 +388,7 @@ public class Contact extends Resource { vcard.addPhoto(new Photo(photo, ImageType.JPEG)); // PRODID, REV - vcard.setProdId("DAVdroid/" + Constants.APP_VERSION + " (ez-vcard/" + Ezvcard.VERSION + ")"); + vcard.setProductId("DAVdroid/" + Constants.APP_VERSION + " (ez-vcard/" + Ezvcard.VERSION + ")"); vcard.setRevision(Revision.now()); // validate and print warnings diff --git a/src/at/bitfire/davdroid/resource/RemoteCollection.java b/src/at/bitfire/davdroid/resource/RemoteCollection.java index 6495101b..5bad96ee 100644 --- a/src/at/bitfire/davdroid/resource/RemoteCollection.java +++ b/src/at/bitfire/davdroid/resource/RemoteCollection.java @@ -28,6 +28,7 @@ import at.bitfire.davdroid.webdav.HttpPropfind; import at.bitfire.davdroid.webdav.WebDavResource; import at.bitfire.davdroid.webdav.WebDavResource.PutMode; import ch.boye.httpclientandroidlib.impl.client.CloseableHttpClient; +import ezvcard.io.text.VCardParseException; /** * Represents a remotely stored synchronizable collection (collection as in @@ -126,7 +127,11 @@ public abstract class RemoteCollection { throw new DavNoContentException(); @Cleanup InputStream is = new ByteArrayInputStream(data); - resource.parseEntity(is); + try { + resource.parseEntity(is); + } catch(VCardParseException e) { + throw new InvalidResourceException(e); + } return resource; } diff --git a/src/at/bitfire/davdroid/syncadapter/AccountSettings.java b/src/at/bitfire/davdroid/syncadapter/AccountSettings.java index abbbb45d..526b1b6f 100644 --- a/src/at/bitfire/davdroid/syncadapter/AccountSettings.java +++ b/src/at/bitfire/davdroid/syncadapter/AccountSettings.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.provider.CalendarContract; import android.provider.CalendarContract.Calendars; import android.util.Log; +import ezvcard.VCardVersion; public class AccountSettings { private final static String TAG = "davdroid.AccountSettings"; @@ -35,7 +36,8 @@ public class AccountSettings { KEY_AUTH_PREEMPTIVE = "auth_preemptive", KEY_ADDRESSBOOK_URL = "addressbook_url", - KEY_ADDRESSBOOK_CTAG = "addressbook_ctag"; + KEY_ADDRESSBOOK_CTAG = "addressbook_ctag", + KEY_ADDRESSBOOK_VCARD_VERSION = "addressbook_vcard_version"; Context context; AccountManager accountManager; @@ -68,6 +70,7 @@ public class AccountSettings { for (ServerInfo.ResourceInfo addressBook : serverInfo.getAddressBooks()) if (addressBook.isEnabled()) { bundle.putString(KEY_ADDRESSBOOK_URL, addressBook.getURL()); + bundle.putString(KEY_ADDRESSBOOK_VCARD_VERSION, addressBook.getVCardVersion().getVersion()); continue; } return bundle; @@ -103,6 +106,14 @@ public class AccountSettings { accountManager.setUserData(account, KEY_ADDRESSBOOK_CTAG, cTag); } + public VCardVersion getAddressBookVCardVersion() { + VCardVersion version = VCardVersion.V3_0; + String versionStr = accountManager.getUserData(account, KEY_ADDRESSBOOK_VCARD_VERSION); + if (versionStr != null) + version = VCardVersion.valueOfByStr(versionStr); + return version; + } + // update from previous account settings diff --git a/src/at/bitfire/davdroid/syncadapter/DavResourceFinder.java b/src/at/bitfire/davdroid/syncadapter/DavResourceFinder.java index 8a1484c9..31159660 100644 --- a/src/at/bitfire/davdroid/syncadapter/DavResourceFinder.java +++ b/src/at/bitfire/davdroid/syncadapter/DavResourceFinder.java @@ -8,6 +8,7 @@ import java.util.List; import ch.boye.httpclientandroidlib.HttpException; import ch.boye.httpclientandroidlib.impl.client.CloseableHttpClient; +import ezvcard.VCardVersion; import android.content.Context; import android.util.Log; import at.bitfire.davdroid.R; @@ -40,7 +41,7 @@ public class DavResourceFinder { WebDavResource homeSetAddressBooks = new WebDavResource(principal, pathAddressBooks); if (checkCapabilities(homeSetAddressBooks, "addressbook")) { - homeSetAddressBooks.propfind(Mode.MEMBERS_COLLECTIONS); + homeSetAddressBooks.propfind(Mode.CARDDAV_COLLECTIONS); List addressBooks = new LinkedList(); if (homeSetAddressBooks.getMembers() != null) @@ -54,6 +55,12 @@ public class DavResourceFinder { resource.getDisplayName(), resource.getDescription(), resource.getColor() ); + + VCardVersion version = resource.getVCardVersion(); + if (version == null) + version = VCardVersion.V3_0; // VCard 3.0 MUST be supported + info.setVCardVersion(version); + addressBooks.add(info); } serverInfo.setAddressBooks(addressBooks); @@ -74,7 +81,7 @@ public class DavResourceFinder { WebDavResource homeSetCalendars = new WebDavResource(principal, pathCalendars); if (checkCapabilities(homeSetCalendars, "calendar-access")) { - homeSetCalendars.propfind(Mode.MEMBERS_COLLECTIONS); + homeSetCalendars.propfind(Mode.CALDAV_COLLECTIONS); List calendars = new LinkedList(); if (homeSetCalendars.getMembers() != null) diff --git a/src/at/bitfire/davdroid/syncadapter/DavSyncAdapter.java b/src/at/bitfire/davdroid/syncadapter/DavSyncAdapter.java index 85c9b6a4..e850060a 100644 --- a/src/at/bitfire/davdroid/syncadapter/DavSyncAdapter.java +++ b/src/at/bitfire/davdroid/syncadapter/DavSyncAdapter.java @@ -117,8 +117,12 @@ public abstract class DavSyncAdapter extends AbstractThreadedSyncAdapter impleme // acquiring read lock before releasing write lock will downgrade the write lock to a read lock httpClientLock.readLock().lock(); httpClientLock.writeLock().unlock(); - - try { + + // TODO use VCard 4.0 if possible + AccountSettings accountSettings = new AccountSettings(getContext(), account); + Log.d(TAG, "Server supports VCard version " + accountSettings.getAddressBookVCardVersion()); + + try { // get local <-> remote collection pairs Map, RemoteCollection> syncCollections = getSyncPairs(account, provider); if (syncCollections == null) diff --git a/src/at/bitfire/davdroid/syncadapter/ServerInfo.java b/src/at/bitfire/davdroid/syncadapter/ServerInfo.java index 839d54d3..e5f11d22 100644 --- a/src/at/bitfire/davdroid/syncadapter/ServerInfo.java +++ b/src/at/bitfire/davdroid/syncadapter/ServerInfo.java @@ -11,6 +11,7 @@ import java.io.Serializable; import java.util.LinkedList; import java.util.List; +import ezvcard.VCardVersion; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -30,6 +31,7 @@ public class ServerInfo implements Serializable { addressBooks = new LinkedList(), calendars = new LinkedList(); + public boolean hasEnabledCalendars() { for (ResourceInfo calendar : calendars) if (calendar.enabled) @@ -53,7 +55,9 @@ public class ServerInfo implements Serializable { final Type type; final boolean readOnly; final String URL, title, description, color; - + + VCardVersion vCardVersion; + String timezone; } } diff --git a/src/at/bitfire/davdroid/webdav/DavMultiget.java b/src/at/bitfire/davdroid/webdav/DavMultiget.java index 7efaeda5..64162b19 100644 --- a/src/at/bitfire/davdroid/webdav/DavMultiget.java +++ b/src/at/bitfire/davdroid/webdav/DavMultiget.java @@ -32,12 +32,12 @@ public class DavMultiget { DavMultiget multiget = (type == Type.ADDRESS_BOOK) ? new DavAddressbookMultiget() : new DavCalendarMultiget(); multiget.prop = new DavProp(); - multiget.prop.getetag = new DavProp.DavPropGetETag(); + multiget.prop.getetag = new DavProp.GetETag(); if (type == Type.ADDRESS_BOOK) - multiget.prop.addressData = new DavProp.DavPropAddressData(); + multiget.prop.addressData = new DavProp.AddressData(); else if (type == Type.CALENDAR) - multiget.prop.calendarData = new DavProp.DavPropCalendarData(); + multiget.prop.calendarData = new DavProp.CalendarData(); multiget.hrefs = new ArrayList(names.length); for (String name : names) diff --git a/src/at/bitfire/davdroid/webdav/DavProp.java b/src/at/bitfire/davdroid/webdav/DavProp.java index 87021796..6c4cf002 100644 --- a/src/at/bitfire/davdroid/webdav/DavProp.java +++ b/src/at/bitfire/davdroid/webdav/DavProp.java @@ -25,19 +25,19 @@ public class DavProp { /* RFC 4918 WebDAV */ @Element(required=false) - DavPropResourceType resourcetype; + ResourceType resourcetype; @Element(required=false) - DavPropDisplayName displayname; + DisplayName displayname; @Element(required=false) - DavPropGetCTag getctag; + GetCTag getctag; @Element(required=false) - DavPropGetETag getetag; + GetETag getetag; @Root(strict=false) - public static class DavPropResourceType { + public static class ResourceType { @Element(required=false) @Getter private Addressbook addressbook; @Element(required=false) @@ -50,18 +50,18 @@ public class DavProp { public static class Calendar { } } - public static class DavPropDisplayName { + public static class DisplayName { @Text(required=false) @Getter private String displayName; } @Namespace(prefix="CS",reference="http://calendarserver.org/ns/") - public static class DavPropGetCTag { + public static class GetCTag { @Text(required=false) @Getter private String CTag; } - public static class DavPropGetETag { + public static class GetETag { @Text(required=false) @Getter private String ETag; } @@ -70,9 +70,9 @@ public class DavProp { /* RFC 5397 WebDAV Current Principal Extension */ @Element(required=false,name="current-user-principal") - DavCurrentUserPrincipal currentUserPrincipal; + CurrentUserPrincipal currentUserPrincipal; - public static class DavCurrentUserPrincipal { + public static class CurrentUserPrincipal { @Element(required=false) @Getter private DavHref href; } @@ -81,9 +81,9 @@ public class DavProp { /* RFC 3744 WebDAV Access Control Protocol */ @ElementList(required=false,name="current-user-privilege-set",entry="privilege") - List currentUserPrivilegeSet; + List currentUserPrivilegeSet; - public static class DavPropPrivilege { + public static class Privilege { @Element(required=false) @Getter private PrivAll all; @@ -111,84 +111,97 @@ public class DavProp { /* RFC 4791 CalDAV, RFC 6352 CardDAV */ @Element(required=false,name="addressbook-home-set") - DavAddressbookHomeSet addressbookHomeSet; + AddressbookHomeSet addressbookHomeSet; @Element(required=false,name="calendar-home-set") - DavCalendarHomeSet calendarHomeSet; + CalendarHomeSet calendarHomeSet; @Element(required=false,name="addressbook-description") - DavPropAddressbookDescription addressbookDescription; + AddressbookDescription addressbookDescription; + + @Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav") + @ElementList(required=false,name="supported-address-data",entry="address-data-type") + List supportedAddressData; @Element(required=false,name="calendar-description") - DavPropCalendarDescription calendarDescription; + CalendarDescription calendarDescription; @Element(required=false,name="calendar-color") - DavPropCalendarColor calendarColor; + CalendarColor calendarColor; @Element(required=false,name="calendar-timezone") - DavPropCalendarTimezone calendarTimezone; + CalendarTimezone calendarTimezone; @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") @ElementList(required=false,name="supported-calendar-component-set",entry="comp") - List supportedCalendarComponentSet; + List supportedCalendarComponentSet; @Element(name="address-data",required=false) - DavPropAddressData addressData; + AddressData addressData; @Element(name="calendar-data",required=false) - DavPropCalendarData calendarData; + CalendarData calendarData; @Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav") - public static class DavAddressbookHomeSet { + public static class AddressbookHomeSet { @Element(required=false) @Getter private DavHref href; } @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") - public static class DavCalendarHomeSet { + public static class CalendarHomeSet { @Element(required=false) @Getter private DavHref href; } @Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav") - public static class DavPropAddressbookDescription { + public static class AddressbookDescription { @Text(required=false) @Getter private String description; } + @Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav") + public static class AddressDataType { + @Attribute(name="content-type") + @Getter private String contentType; + + @Attribute + @Getter private String version; + } + @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") - public static class DavPropCalendarDescription { + public static class CalendarDescription { @Text(required=false) @Getter private String description; } @Namespace(prefix="A",reference="http://apple.com/ns/ical/") - public static class DavPropCalendarColor { + public static class CalendarColor { @Text(required=false) @Getter private String color; } @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") - public static class DavPropCalendarTimezone { + public static class CalendarTimezone { @Text(required=false) @Getter private String timezone; } @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") - public static class DavPropComp { + public static class Comp { @Attribute @Getter String name; } @Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav") - public static class DavPropAddressData { + public static class AddressData { @Text(required=false) @Getter String vcard; } @Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav") - public static class DavPropCalendarData { + public static class CalendarData { @Text(required=false) @Getter String ical; } diff --git a/src/at/bitfire/davdroid/webdav/HttpPropfind.java b/src/at/bitfire/davdroid/webdav/HttpPropfind.java index 8663ac71..896367eb 100644 --- a/src/at/bitfire/davdroid/webdav/HttpPropfind.java +++ b/src/at/bitfire/davdroid/webdav/HttpPropfind.java @@ -26,7 +26,8 @@ public class HttpPropfind extends HttpEntityEnclosingRequestBase { public enum Mode { CURRENT_USER_PRINCIPAL, HOME_SETS, - MEMBERS_COLLECTIONS, + CARDDAV_COLLECTIONS, + CALDAV_COLLECTIONS, COLLECTION_CTAG, MEMBERS_ETAG } @@ -47,30 +48,37 @@ public class HttpPropfind extends HttpEntityEnclosingRequestBase { int depth = 0; switch (mode) { case CURRENT_USER_PRINCIPAL: - propfind.prop.currentUserPrincipal = new DavProp.DavCurrentUserPrincipal(); + propfind.prop.currentUserPrincipal = new DavProp.CurrentUserPrincipal(); break; case HOME_SETS: - propfind.prop.addressbookHomeSet = new DavProp.DavAddressbookHomeSet(); - propfind.prop.calendarHomeSet = new DavProp.DavCalendarHomeSet(); + propfind.prop.addressbookHomeSet = new DavProp.AddressbookHomeSet(); + propfind.prop.calendarHomeSet = new DavProp.CalendarHomeSet(); break; - case MEMBERS_COLLECTIONS: + case CARDDAV_COLLECTIONS: depth = 1; - propfind.prop.displayname = new DavProp.DavPropDisplayName(); - propfind.prop.resourcetype = new DavProp.DavPropResourceType(); - propfind.prop.currentUserPrivilegeSet = new LinkedList(); - propfind.prop.addressbookDescription = new DavProp.DavPropAddressbookDescription(); - propfind.prop.calendarDescription = new DavProp.DavPropCalendarDescription(); - propfind.prop.calendarColor = new DavProp.DavPropCalendarColor(); - propfind.prop.calendarTimezone = new DavProp.DavPropCalendarTimezone(); - propfind.prop.supportedCalendarComponentSet = new LinkedList(); + propfind.prop.displayname = new DavProp.DisplayName(); + propfind.prop.resourcetype = new DavProp.ResourceType(); + propfind.prop.currentUserPrivilegeSet = new LinkedList(); + propfind.prop.addressbookDescription = new DavProp.AddressbookDescription(); + propfind.prop.supportedAddressData = new LinkedList(); + break; + case CALDAV_COLLECTIONS: + depth = 1; + propfind.prop.displayname = new DavProp.DisplayName(); + propfind.prop.resourcetype = new DavProp.ResourceType(); + propfind.prop.currentUserPrivilegeSet = new LinkedList(); + propfind.prop.calendarDescription = new DavProp.CalendarDescription(); + propfind.prop.calendarColor = new DavProp.CalendarColor(); + propfind.prop.calendarTimezone = new DavProp.CalendarTimezone(); + propfind.prop.supportedCalendarComponentSet = new LinkedList(); break; case COLLECTION_CTAG: - propfind.prop.getctag = new DavProp.DavPropGetCTag(); + propfind.prop.getctag = new DavProp.GetCTag(); break; case MEMBERS_ETAG: depth = 1; - propfind.prop.getctag = new DavProp.DavPropGetCTag(); - propfind.prop.getetag = new DavProp.DavPropGetETag(); + propfind.prop.getctag = new DavProp.GetCTag(); + propfind.prop.getetag = new DavProp.GetETag(); break; } diff --git a/src/at/bitfire/davdroid/webdav/WebDavResource.java b/src/at/bitfire/davdroid/webdav/WebDavResource.java index a9b18e9f..d7b15a84 100644 --- a/src/at/bitfire/davdroid/webdav/WebDavResource.java +++ b/src/at/bitfire/davdroid/webdav/WebDavResource.java @@ -30,7 +30,7 @@ import org.simpleframework.xml.core.Persister; import android.util.Log; import at.bitfire.davdroid.URIUtils; import at.bitfire.davdroid.resource.Event; -import at.bitfire.davdroid.webdav.DavProp.DavPropComp; +import at.bitfire.davdroid.webdav.DavProp.Comp; import ch.boye.httpclientandroidlib.Header; import ch.boye.httpclientandroidlib.HttpEntity; import ch.boye.httpclientandroidlib.HttpHost; @@ -53,6 +53,7 @@ import ch.boye.httpclientandroidlib.impl.client.BasicCredentialsProvider; import ch.boye.httpclientandroidlib.impl.client.CloseableHttpClient; import ch.boye.httpclientandroidlib.message.BasicLineParser; import ch.boye.httpclientandroidlib.util.EntityUtils; +import ezvcard.VCardVersion; /** @@ -64,14 +65,12 @@ public class WebDavResource { private static final String TAG = "davdroid.WebDavResource"; public enum Property { - CURRENT_USER_PRINCIPAL, - READ_ONLY, - DISPLAY_NAME, DESCRIPTION, COLOR, - TIMEZONE, SUPPORTED_COMPONENTS, + CURRENT_USER_PRINCIPAL, // resource detection ADDRESSBOOK_HOMESET, CALENDAR_HOMESET, - IS_ADDRESSBOOK, IS_CALENDAR, - CTAG, ETAG, - CONTENT_TYPE + CONTENT_TYPE, READ_ONLY, // WebDAV (common) + DISPLAY_NAME, DESCRIPTION, CTAG, ETAG, + IS_CALENDAR, COLOR, TIMEZONE, // CalDAV + IS_ADDRESSBOOK, VCARD_VERSION // CardDAV } public enum PutMode { ADD_DONT_OVERWRITE, @@ -189,6 +188,22 @@ public class WebDavResource { return properties.get(Property.CURRENT_USER_PRINCIPAL); } + public String getAddressbookHomeSet() { + return properties.get(Property.ADDRESSBOOK_HOMESET); + } + + public String getCalendarHomeSet() { + return properties.get(Property.CALENDAR_HOMESET); + } + + public String getContentType() { + return properties.get(Property.CONTENT_TYPE); + } + + public void setContentType(String mimeType) { + properties.put(Property.CONTENT_TYPE, mimeType); + } + public boolean isReadOnly() { return properties.containsKey(Property.READ_ONLY); } @@ -201,22 +216,6 @@ public class WebDavResource { return properties.get(Property.DESCRIPTION); } - public String getColor() { - return properties.get(Property.COLOR); - } - - public String getTimezone() { - return properties.get(Property.TIMEZONE); - } - - public String getAddressbookHomeSet() { - return properties.get(Property.ADDRESSBOOK_HOMESET); - } - - public String getCalendarHomeSet() { - return properties.get(Property.CALENDAR_HOMESET); - } - public String getCTag() { return properties.get(Property.CTAG); } @@ -227,21 +226,26 @@ public class WebDavResource { public String getETag() { return properties.get(Property.ETAG); } - - public String getContentType() { - return properties.get(Property.CONTENT_TYPE); + + public boolean isCalendar() { + return properties.containsKey(Property.IS_CALENDAR); } - public void setContentType(String mimeType) { - properties.put(Property.CONTENT_TYPE, mimeType); + public String getColor() { + return properties.get(Property.COLOR); + } + + public String getTimezone() { + return properties.get(Property.TIMEZONE); } public boolean isAddressBook() { return properties.containsKey(Property.IS_ADDRESSBOOK); } - public boolean isCalendar() { - return properties.containsKey(Property.IS_CALENDAR); + public VCardVersion getVCardVersion() { + String versionStr = properties.get(Property.VCARD_VERSION); + return (versionStr != null) ? VCardVersion.valueOfByStr(versionStr) : null; } @@ -500,7 +504,7 @@ public class WebDavResource { mayUnbind = false, mayWrite = false, mayWriteContent = false; - for (DavProp.DavPropPrivilege privilege : prop.currentUserPrivilegeSet) { + for (DavProp.Privilege privilege : prop.currentUserPrivilegeSet) { if (privilege.getAll() != null) mayAll = true; if (privilege.getBind() != null) mayBind = true; if (privilege.getUnbind() != null) mayUnbind = true; @@ -514,20 +518,26 @@ public class WebDavResource { if (prop.addressbookHomeSet != null && prop.addressbookHomeSet.getHref() != null) properties.put(Property.ADDRESSBOOK_HOMESET, prop.addressbookHomeSet.getHref().href); - if (singlePropstat.prop.calendarHomeSet != null && prop.calendarHomeSet.getHref() != null) + if (prop.calendarHomeSet != null && prop.calendarHomeSet.getHref() != null) properties.put(Property.CALENDAR_HOMESET, prop.calendarHomeSet.getHref().href); if (prop.displayname != null) properties.put(Property.DISPLAY_NAME, prop.displayname.getDisplayName()); if (prop.resourcetype != null) { - if (prop.resourcetype.getAddressbook() != null) { + if (prop.resourcetype.getAddressbook() != null) { // CardDAV collection properties properties.put(Property.IS_ADDRESSBOOK, "1"); if (prop.addressbookDescription != null) properties.put(Property.DESCRIPTION, prop.addressbookDescription.getDescription()); + if (prop.supportedAddressData != null) + for (DavProp.AddressDataType dataType : prop.supportedAddressData) + if ("text/vcard".equalsIgnoreCase(dataType.getContentType())) + // ignore "3.0" as it MUST be supported anyway + if ("4.0".equals(dataType.getVersion())) + properties.put(Property.VCARD_VERSION, VCardVersion.V4_0.getVersion()); } - if (prop.resourcetype.getCalendar() != null) { + if (prop.resourcetype.getCalendar() != null) { // CalDAV collection propertioes properties.put(Property.IS_CALENDAR, "1"); if (prop.calendarDescription != null) @@ -541,7 +551,7 @@ public class WebDavResource { if (prop.supportedCalendarComponentSet != null) { referenced.supportedComponents = new LinkedList(); - for (DavPropComp component : prop.supportedCalendarComponentSet) + for (Comp component : prop.supportedCalendarComponentSet) referenced.supportedComponents.add(component.getName()); } } diff --git a/test/robohydra/plugins/dav/index.js b/test/robohydra/plugins/dav/index.js index f3bd64d1..edda3c08 100644 --- a/test/robohydra/plugins/dav/index.js +++ b/test/robohydra/plugins/dav/index.js @@ -10,7 +10,7 @@ exports.getBodyParts = function(conf) { new RoboHydraHeadDAV({ path: "/dav/principals/users/test", handler: function(req,res,next) { - if (req.method == "PROPFIND" && req.rawBody.toString().match(/home-set/)) { + if (req.method == "PROPFIND" && req.rawBody.toString().match(/home-?set/)) { res.statusCode = 207; res.write('\\ \ @@ -56,7 +56,7 @@ exports.getBodyParts = function(conf) { \ \ \ - /dav/addressbooks/test/default.vcf/\ + /dav/addressbooks/test/default-v4.vcf/\ \ \ \ @@ -64,6 +64,10 @@ exports.getBodyParts = function(conf) { \ \ Default Address Book\ + \ + \ + \ + \ \ HTTP/1.1 200 OK\ \ @@ -78,7 +82,7 @@ exports.getBodyParts = function(conf) { new RoboHydraHeadDAV({ path: "/dav/calendars/test/", handler: function(req,res,next) { - if (req.method == "PROPFIND" && req.rawBody.toString().match(/addressbook-description/)) { + if (req.method == "PROPFIND" && req.rawBody.toString().match(/calendar-description/)) { res.statusCode = 207; res.write('\\ \ diff --git a/test/src/at/bitfire/davdroid/syncadapter/DavResourceFinderTest.java b/test/src/at/bitfire/davdroid/syncadapter/DavResourceFinderTest.java index a19be04c..12406189 100644 --- a/test/src/at/bitfire/davdroid/syncadapter/DavResourceFinderTest.java +++ b/test/src/at/bitfire/davdroid/syncadapter/DavResourceFinderTest.java @@ -2,6 +2,7 @@ package at.bitfire.davdroid.syncadapter; import java.util.List; +import ezvcard.VCardVersion; import android.test.InstrumentationTestCase; import at.bitfire.davdroid.syncadapter.ServerInfo.ResourceInfo; import at.bitfire.davdroid.test.Constants; @@ -18,6 +19,7 @@ public class DavResourceFinderTest extends InstrumentationTestCase { assertEquals(1, collections.size()); assertEquals("Default Address Book", collections.get(0).getDescription()); + assertEquals(VCardVersion.V4_0, collections.get(0).getVCardVersion()); // CalDAV assertTrue(info.isCalDAV()); diff --git a/test/src/at/bitfire/davdroid/test/ContactTest.java b/test/src/at/bitfire/davdroid/test/ContactTest.java index d9d437cf..a98ed78f 100644 --- a/test/src/at/bitfire/davdroid/test/ContactTest.java +++ b/test/src/at/bitfire/davdroid/test/ContactTest.java @@ -15,7 +15,6 @@ import net.fortuna.ical4j.data.ParserException; import android.content.res.AssetManager; import android.test.InstrumentationTestCase; import at.bitfire.davdroid.resource.Contact; -import ezvcard.VCardException; import ezvcard.property.Impp; public class ContactTest extends InstrumentationTestCase { @@ -25,7 +24,7 @@ public class ContactTest extends InstrumentationTestCase { assetMgr = getInstrumentation().getContext().getResources().getAssets(); } - public void testIMPP() throws VCardException, IOException { + public void testIMPP() throws IOException { Contact c = parseVCard("impp.vcf"); assertEquals("test mctest", c.getDisplayName()); @@ -52,7 +51,7 @@ public class ContactTest extends InstrumentationTestCase { } - private Contact parseVCard(String fileName) throws VCardException, IOException { + private Contact parseVCard(String fileName) throws IOException { @Cleanup InputStream in = assetMgr.open(fileName, AssetManager.ACCESS_STREAMING); Contact c = new Contact(fileName, null); diff --git a/test/src/at/bitfire/davdroid/webdav/WebDavResourceTest.java b/test/src/at/bitfire/davdroid/webdav/WebDavResourceTest.java index 0203d19f..3c427b8d 100644 --- a/test/src/at/bitfire/davdroid/webdav/WebDavResourceTest.java +++ b/test/src/at/bitfire/davdroid/webdav/WebDavResourceTest.java @@ -109,10 +109,10 @@ public class WebDavResourceTest extends InstrumentationTestCase { public void testPropfindAddressBooks() throws IOException, HttpException, DavException { WebDavResource dav = new WebDavResource(davCollection, "addressbooks/test"); - dav.propfind(HttpPropfind.Mode.MEMBERS_COLLECTIONS); + dav.propfind(HttpPropfind.Mode.CARDDAV_COLLECTIONS); assertEquals(2, dav.getMembers().size()); for (WebDavResource member : dav.getMembers()) { - if (member.getName().equals("default.vcf")) + if (member.getName().equals("default-v4.vcf")) assertTrue(member.isAddressBook()); else assertFalse(member.isAddressBook()); @@ -122,7 +122,7 @@ public class WebDavResourceTest extends InstrumentationTestCase { public void testPropfindCalendars() throws IOException, HttpException, DavException { WebDavResource dav = new WebDavResource(davCollection, "calendars/test"); - dav.propfind(HttpPropfind.Mode.MEMBERS_COLLECTIONS); + dav.propfind(HttpPropfind.Mode.CALDAV_COLLECTIONS); assertEquals(3, dav.getMembers().size()); assertEquals("0xFF00FF", dav.getMembers().get(2).getColor()); for (WebDavResource member : dav.getMembers()) { @@ -217,7 +217,7 @@ public class WebDavResourceTest extends InstrumentationTestCase { public void testInvalidURLs() throws IOException, HttpException, DavException { WebDavResource dav = new WebDavResource(davInvalid, "addressbooks/user%40domain/"); - dav.propfind(HttpPropfind.Mode.MEMBERS_COLLECTIONS); + dav.propfind(HttpPropfind.Mode.CARDDAV_COLLECTIONS); List members = dav.getMembers(); assertEquals(2, members.size()); assertEquals(Constants.ROBOHYDRA_BASE + "dav/addressbooks/user%40domain/My%20Contacts%3a1.vcf/", members.get(0).getLocation().toString());