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:
parent
cd513683f5
commit
5f3c6045d8
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,8 +78,28 @@ 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 {
|
||||||
collection.propfind(HttpPropfind.Mode.MEMBERS_ETAG);
|
String query = getMemberETagsQuery();
|
||||||
|
if (query != null)
|
||||||
|
collection.report(query);
|
||||||
|
else
|
||||||
|
collection.propfind(HttpPropfind.Mode.MEMBERS_ETAG);
|
||||||
|
|
||||||
List<T> resources = new LinkedList<T>();
|
List<T> resources = new LinkedList<T>();
|
||||||
if (collection.getMembers() != null)
|
if (collection.getMembers() != null)
|
||||||
@ -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)");
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
13
app/src/main/java/at/bitfire/davdroid/webdav/DavFilter.java
Normal file
13
app/src/main/java/at/bitfire/davdroid/webdav/DavFilter.java
Normal 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;
|
||||||
|
}
|
@ -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 {
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user