1
0
mirror of https://github.com/etesync/android synced 2024-11-26 09:58:11 +00:00

Implement remote filters to fetch only CalDAV resources with useful components (VEVENT for now)

This commit is contained in:
Ricki Hirner 2015-05-15 23:35:27 +02:00
parent cd513683f5
commit 5f3c6045d8
9 changed files with 147 additions and 10 deletions

View File

@ -8,15 +8,30 @@
package at.bitfire.davdroid.resource; package at.bitfire.davdroid.resource;
import android.accounts.Account; import android.accounts.Account;
import android.util.Log;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.StringWriter;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import at.bitfire.davdroid.syncadapter.AccountSettings; import at.bitfire.davdroid.syncadapter.AccountSettings;
import at.bitfire.davdroid.webdav.DavCalendarQuery;
import at.bitfire.davdroid.webdav.DavCompFilter;
import at.bitfire.davdroid.webdav.DavFilter;
import at.bitfire.davdroid.webdav.DavMultiget; import at.bitfire.davdroid.webdav.DavMultiget;
import at.bitfire.davdroid.webdav.DavProp;
public class CalDavCalendar extends RemoteCollection<Event> { public class CalDavCalendar extends RemoteCollection<Event> {
private final static String TAG = "davdroid.CalDAVCalendar";
public CalDavCalendar(CloseableHttpClient httpClient, String baseURL, String user, String password, boolean preemptiveAuth) throws URISyntaxException {
super(httpClient, baseURL, user, password, preemptiveAuth);
}
@Override @Override
protected String memberAcceptedMimeTypes() protected String memberAcceptedMimeTypes()
@ -35,7 +50,33 @@ public class CalDavCalendar extends RemoteCollection<Event> {
} }
public CalDavCalendar(CloseableHttpClient httpClient, String baseURL, String user, String password, boolean preemptiveAuth) throws URISyntaxException { @Override
super(httpClient, baseURL, user, password, preemptiveAuth); public String getMemberETagsQuery() {
DavCalendarQuery query = new DavCalendarQuery();
// prop
DavProp prop = new DavProp();
prop.setGetetag(new DavProp.GetETag());
query.setProp(prop);
// filter
DavFilter filter = new DavFilter();
query.setFilter(filter);
DavCompFilter compFilter = new DavCompFilter("VCALENDAR");
filter.setCompFilter(compFilter);
compFilter.setCompFilter(new DavCompFilter("VEVENT"));
Serializer serializer = new Persister();
StringWriter writer = new StringWriter();
try {
serializer.write(query, writer);
} catch (Exception e) {
Log.e(TAG, "Couldn't prepare REPORT query", e);
return null;
}
return writer.toString();
} }
} }

View File

@ -26,7 +26,9 @@ import java.util.List;
import at.bitfire.davdroid.URIUtils; import at.bitfire.davdroid.URIUtils;
import at.bitfire.davdroid.syncadapter.AccountSettings; import at.bitfire.davdroid.syncadapter.AccountSettings;
import at.bitfire.davdroid.webdav.DavCalendarQuery;
import at.bitfire.davdroid.webdav.DavException; import at.bitfire.davdroid.webdav.DavException;
import at.bitfire.davdroid.webdav.DavFilter;
import at.bitfire.davdroid.webdav.DavMultiget; import at.bitfire.davdroid.webdav.DavMultiget;
import at.bitfire.davdroid.webdav.DavNoContentException; import at.bitfire.davdroid.webdav.DavNoContentException;
import at.bitfire.davdroid.webdav.HttpException; import at.bitfire.davdroid.webdav.HttpException;
@ -36,6 +38,7 @@ import at.bitfire.davdroid.webdav.WebDavResource.PutMode;
import ezvcard.io.text.VCardParseException; import ezvcard.io.text.VCardParseException;
import lombok.Cleanup; import lombok.Cleanup;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
/** /**
* Represents a remotely stored synchronizable collection (collection as in * Represents a remotely stored synchronizable collection (collection as in
@ -75,7 +78,27 @@ public abstract class RemoteCollection<T extends Resource> {
return collection.getCTag(); return collection.getCTag();
} }
/**
* Returns a body for the REPORT request that queries all members of the collection
* that should be considered. Allows collections to implement remote filters.
* @return body for REPORT request or null if PROPFIND shall be used
*/
public String getMemberETagsQuery() {
return null;
}
/**
* Gets the ETags of the resources in a collection. If davQuery is set, it's required to be a
* complete addressbook-query or calendar-query XML and will cause getMemberETags() to use REPORT
* instead of PROPFIND.
* @return array of Resources where only the resource names and ETags are set
*/
public Resource[] getMemberETags() throws URISyntaxException, IOException, DavException, HttpException { public Resource[] getMemberETags() throws URISyntaxException, IOException, DavException, HttpException {
String query = getMemberETagsQuery();
if (query != null)
collection.report(query);
else
collection.propfind(HttpPropfind.Mode.MEMBERS_ETAG); collection.propfind(HttpPropfind.Mode.MEMBERS_ETAG);
List<T> resources = new LinkedList<T>(); List<T> resources = new LinkedList<T>();
@ -84,13 +107,15 @@ public abstract class RemoteCollection<T extends Resource> {
resources.add(newResourceSkeleton(member.getName(), member.getETag())); resources.add(newResourceSkeleton(member.getName(), member.getETag()));
return resources.toArray(new Resource[0]); return resources.toArray(new Resource[0]);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Resource[] multiGet(Resource[] resources) throws URISyntaxException, IOException, DavException, HttpException { public Resource[] multiGet(Resource[] resources) throws URISyntaxException, IOException, DavException, HttpException {
try { try {
if (resources.length == 1) if (resources.length == 1)
return (T[]) new Resource[]{get(resources[0])}; return (T[]) new Resource[] { get(resources[0]) };
Log.i(TAG, "Multi-getting " + resources.length + " remote resource(s)"); Log.i(TAG, "Multi-getting " + resources.length + " remote resource(s)");

View File

@ -48,7 +48,7 @@ public class CalendarsSyncAdapterService extends Service {
private static class SyncAdapter extends DavSyncAdapter { private static class SyncAdapter extends DavSyncAdapter {
private final static String TAG = "davdroid.CalendarsSyncAdapter"; private final static String TAG = "davdroid.CalDAVSync";
private SyncAdapter(Context context) { private SyncAdapter(Context context) {

View File

@ -47,7 +47,7 @@ public class ContactsSyncAdapterService extends Service {
private static class ContactsSyncAdapter extends DavSyncAdapter { private static class ContactsSyncAdapter extends DavSyncAdapter {
private final static String TAG = "davdroid.ContactsSyncAdapter"; private final static String TAG = "davdroid.CardDAVSync";
private ContactsSyncAdapter(Context context) { private ContactsSyncAdapter(Context context) {

View File

@ -0,0 +1,23 @@
package at.bitfire.davdroid.webdav;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
import lombok.Getter;
import lombok.Setter;
@Root(name="calendar-query")
@NamespaceList({
@Namespace(reference="DAV:"),
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
})
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
public class DavCalendarQuery {
@Element
@Getter @Setter DavProp prop;
@Element
@Getter @Setter DavFilter filter;
}

View File

@ -0,0 +1,23 @@
package at.bitfire.davdroid.webdav;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;
import lombok.Getter;
import lombok.Setter;
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
public class DavCompFilter {
public DavCompFilter(String name) {
this.name = name;
}
@Attribute(required=false)
String name;
@Element(required=false,name="comp-filter")
@Getter @Setter DavCompFilter compFilter;
}

View File

@ -0,0 +1,13 @@
package at.bitfire.davdroid.webdav;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import lombok.Getter;
import lombok.Setter;
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
public class DavFilter {
@Element(required=false)
@Getter @Setter DavCompFilter compFilter;
}

View File

@ -35,7 +35,7 @@ public class DavProp {
GetCTag getctag; GetCTag getctag;
@Element(required=false) @Element(required=false)
GetETag getetag; @Setter GetETag getetag;
@Root(strict=false) @Root(strict=false)
public static class ResourceType { public static class ResourceType {

View File

@ -332,6 +332,18 @@ public class WebDavResource {
processMultiStatus(response); processMultiStatus(response);
} }
public void report(String query) throws IOException, HttpException, DavException {
HttpReport report = new HttpReport(location, query);
report.setHeader("Depth", "1");
@Cleanup CloseableHttpResponse response = httpClient.execute(report, context);
if (response == null)
throw new DavNoContentException();
checkResponse(response);
processMultiStatus(response);
}
/* resource operations */ /* resource operations */