mirror of
https://github.com/etesync/android
synced 2024-12-23 07:08:16 +00:00
VCard 4 support detection; new ez-vcard version
* detect CardDAV VCard version support using supported-address-data + test * account setting for supported VCard version * don't ask for calendar details when querying CardDAV collections * don't ask for address book details when querying CalDAV collections * ez-vcard update to 0.9.5 (fixes #268), adapted exception handling * refactoring: unnecessary DavProp prefixes removed
This commit is contained in:
parent
2c79ae20e5
commit
bdee53b5ab
Binary file not shown.
BIN
libs/ez-vcard-0.9.5.jar
Normal file
BIN
libs/ez-vcard-0.9.5.jar
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -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<T extends Resource> {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<ServerInfo.ResourceInfo> addressBooks = new LinkedList<ServerInfo.ResourceInfo>();
|
||||
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<ServerInfo.ResourceInfo> calendars = new LinkedList<ServerInfo.ResourceInfo>();
|
||||
if (homeSetCalendars.getMembers() != null)
|
||||
|
@ -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<LocalCollection<?>, RemoteCollection<?>> syncCollections = getSyncPairs(account, provider);
|
||||
if (syncCollections == null)
|
||||
|
@ -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<ResourceInfo>(),
|
||||
calendars = new LinkedList<ResourceInfo>();
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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<DavHref>(names.length);
|
||||
for (String name : names)
|
||||
|
@ -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<DavPropPrivilege> currentUserPrivilegeSet;
|
||||
List<Privilege> 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<AddressDataType> 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<DavPropComp> supportedCalendarComponentSet;
|
||||
List<Comp> 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;
|
||||
}
|
||||
|
@ -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<DavProp.DavPropPrivilege>();
|
||||
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<DavProp.DavPropComp>();
|
||||
propfind.prop.displayname = new DavProp.DisplayName();
|
||||
propfind.prop.resourcetype = new DavProp.ResourceType();
|
||||
propfind.prop.currentUserPrivilegeSet = new LinkedList<DavProp.Privilege>();
|
||||
propfind.prop.addressbookDescription = new DavProp.AddressbookDescription();
|
||||
propfind.prop.supportedAddressData = new LinkedList<DavProp.AddressDataType>();
|
||||
break;
|
||||
case CALDAV_COLLECTIONS:
|
||||
depth = 1;
|
||||
propfind.prop.displayname = new DavProp.DisplayName();
|
||||
propfind.prop.resourcetype = new DavProp.ResourceType();
|
||||
propfind.prop.currentUserPrivilegeSet = new LinkedList<DavProp.Privilege>();
|
||||
propfind.prop.calendarDescription = new DavProp.CalendarDescription();
|
||||
propfind.prop.calendarColor = new DavProp.CalendarColor();
|
||||
propfind.prop.calendarTimezone = new DavProp.CalendarTimezone();
|
||||
propfind.prop.supportedCalendarComponentSet = new LinkedList<DavProp.Comp>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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<String>();
|
||||
for (DavPropComp component : prop.supportedCalendarComponentSet)
|
||||
for (Comp component : prop.supportedCalendarComponentSet)
|
||||
referenced.supportedComponents.add(component.getName());
|
||||
}
|
||||
}
|
||||
|
@ -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('\<?xml version="1.0" encoding="utf-8" ?>\
|
||||
<multistatus xmlns="DAV:">\
|
||||
@ -56,7 +56,7 @@ exports.getBodyParts = function(conf) {
|
||||
</propstat>\
|
||||
</response>\
|
||||
<response>\
|
||||
<href>/dav/addressbooks/test/default.vcf/</href>\
|
||||
<href>/dav/addressbooks/test/default-v4.vcf/</href>\
|
||||
<propstat>\
|
||||
<prop xmlns:CARD="urn:ietf:params:xml:ns:carddav">\
|
||||
<resourcetype>\
|
||||
@ -64,6 +64,10 @@ exports.getBodyParts = function(conf) {
|
||||
<CARD:addressbook/>\
|
||||
</resourcetype>\
|
||||
<CARD:addressbook-description>Default Address Book</CARD:addressbook-description>\
|
||||
<CARD:supported-address-data>\
|
||||
<CARD:address-data-type content-type="text/vcard" version="3.0" />\
|
||||
<CARD:address-data-type content-type="text/vcard" version="4.0" />\
|
||||
</CARD:supported-address-data>\
|
||||
</prop>\
|
||||
<status>HTTP/1.1 200 OK</status>\
|
||||
</propstat>\
|
||||
@ -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('\<?xml version="1.0" encoding="utf-8" ?>\
|
||||
<multistatus xmlns="DAV:" xmlns:CAL="urn:ietf:params:xml:ns:caldav">\
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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<WebDavResource> members = dav.getMembers();
|
||||
assertEquals(2, members.size());
|
||||
assertEquals(Constants.ROBOHYDRA_BASE + "dav/addressbooks/user%40domain/My%20Contacts%3a1.vcf/", members.get(0).getLocation().toString());
|
||||
|
Loading…
Reference in New Issue
Block a user