mirror of
https://github.com/etesync/android
synced 2024-11-22 16:08:13 +00:00
Bug fixes:
* calendar multi-get * debug output for propfind/multiget requests * setup GUI crash if no address book/calendar available
This commit is contained in:
parent
c012512de1
commit
62ed38ee4f
@ -247,4 +247,8 @@ public class Contact extends Resource {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws ValidationException {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import net.fortuna.ical4j.model.DefaultTimeZoneRegistryFactory;
|
|||||||
import net.fortuna.ical4j.model.Property;
|
import net.fortuna.ical4j.model.Property;
|
||||||
import net.fortuna.ical4j.model.PropertyList;
|
import net.fortuna.ical4j.model.PropertyList;
|
||||||
import net.fortuna.ical4j.model.TimeZoneRegistry;
|
import net.fortuna.ical4j.model.TimeZoneRegistry;
|
||||||
|
import net.fortuna.ical4j.model.ValidationException;
|
||||||
import net.fortuna.ical4j.model.component.VEvent;
|
import net.fortuna.ical4j.model.component.VEvent;
|
||||||
import net.fortuna.ical4j.model.parameter.Value;
|
import net.fortuna.ical4j.model.parameter.Value;
|
||||||
import net.fortuna.ical4j.model.property.Attendee;
|
import net.fortuna.ical4j.model.property.Attendee;
|
||||||
@ -290,4 +291,11 @@ public class Event extends Resource {
|
|||||||
Log.i(TAG, "Assuming time zone " + localTZ + " for " + tzID);
|
Log.i(TAG, "Assuming time zone " + localTZ + " for " + tzID);
|
||||||
date.setTimeZone(tzRegistry.getTimeZone(localTZ));
|
date.setTimeZone(tzRegistry.getTimeZone(localTZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws ValidationException {
|
||||||
|
if (dtStart == null)
|
||||||
|
throw new ValidationException("dtStart empty");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import net.fortuna.ical4j.model.ValidationException;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
@ -111,7 +113,9 @@ public abstract class LocalCollection<ResourceType extends Resource> {
|
|||||||
|
|
||||||
// create/update/delete
|
// create/update/delete
|
||||||
|
|
||||||
public void add(ResourceType resource) {
|
public void add(ResourceType resource) throws ValidationException {
|
||||||
|
resource.validate();
|
||||||
|
|
||||||
int idx = pendingOperations.size();
|
int idx = pendingOperations.size();
|
||||||
pendingOperations.add(
|
pendingOperations.add(
|
||||||
buildEntry(ContentProviderOperation.newInsert(entriesURI()), resource)
|
buildEntry(ContentProviderOperation.newInsert(entriesURI()), resource)
|
||||||
@ -121,8 +125,10 @@ public abstract class LocalCollection<ResourceType extends Resource> {
|
|||||||
addDataRows(resource, -1, idx);
|
addDataRows(resource, -1, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateByRemoteName(ResourceType remoteResource) throws RemoteException {
|
public void updateByRemoteName(ResourceType remoteResource) throws RemoteException, ValidationException {
|
||||||
ResourceType localResource = findByRemoteName(remoteResource.getName());
|
ResourceType localResource = findByRemoteName(remoteResource.getName());
|
||||||
|
|
||||||
|
remoteResource.validate();
|
||||||
|
|
||||||
pendingOperations.add(
|
pendingOperations.add(
|
||||||
buildEntry(ContentProviderOperation.newUpdate(ContentUris.withAppendedId(entriesURI(), localResource.getLocalID())), remoteResource)
|
buildEntry(ContentProviderOperation.newUpdate(ContentUris.withAppendedId(entriesURI(), localResource.getLocalID())), remoteResource)
|
||||||
|
@ -38,4 +38,6 @@ public abstract class Resource {
|
|||||||
|
|
||||||
public abstract void parseEntity(InputStream entity) throws IOException, ParserException;
|
public abstract void parseEntity(InputStream entity) throws IOException, ParserException;
|
||||||
public abstract String toEntity() throws IOException, ValidationException;
|
public abstract String toEntity() throws IOException, ValidationException;
|
||||||
|
|
||||||
|
public abstract void validate() throws ValidationException;
|
||||||
}
|
}
|
||||||
|
@ -93,13 +93,13 @@ public class CalendarsSyncAdapterService extends Service {
|
|||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.getLocalizedMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
syncResult.stats.numIoExceptions++;
|
syncResult.stats.numIoExceptions++;
|
||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.toString());
|
||||||
} catch (IncapableResourceException e) {
|
} catch (IncapableResourceException e) {
|
||||||
syncResult.stats.numParseExceptions++;
|
syncResult.stats.numParseExceptions++;
|
||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.toString());
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
syncResult.stats.numParseExceptions++;
|
syncResult.stats.numParseExceptions++;
|
||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ public class SelectCollectionsAdapter extends BaseAdapter implements ListAdapter
|
|||||||
|
|
||||||
public SelectCollectionsAdapter(ServerInfo serverInfo) {
|
public SelectCollectionsAdapter(ServerInfo serverInfo) {
|
||||||
this.serverInfo = serverInfo;
|
this.serverInfo = serverInfo;
|
||||||
nAddressBooks = serverInfo.getAddressBooks().size();
|
nAddressBooks = (serverInfo.getAddressBooks() == null) ? 0 : serverInfo.getAddressBooks().size();
|
||||||
nCalendars = serverInfo.getCalendars().size();
|
nCalendars = (serverInfo.getCalendars() == null) ? 0 : serverInfo.getCalendars().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +137,11 @@ public class SyncManager {
|
|||||||
if (!resourcesToAdd.isEmpty())
|
if (!resourcesToAdd.isEmpty())
|
||||||
for (Resource res : dav.multiGet(resourcesToAdd.toArray(new Resource[0]))) {
|
for (Resource res : dav.multiGet(resourcesToAdd.toArray(new Resource[0]))) {
|
||||||
Log.i(TAG, "Adding " + res.getName());
|
Log.i(TAG, "Adding " + res.getName());
|
||||||
local.add(res);
|
try {
|
||||||
|
local.add(res);
|
||||||
|
} catch (ValidationException e) {
|
||||||
|
Log.e(TAG, "Invalid resource: " + res.getName());
|
||||||
|
}
|
||||||
syncResult.stats.numInserts++;
|
syncResult.stats.numInserts++;
|
||||||
}
|
}
|
||||||
local.commit();
|
local.commit();
|
||||||
@ -145,7 +149,11 @@ public class SyncManager {
|
|||||||
Log.i(TAG, "Updating " + resourcesToUpdate.size() + " remote resource(s)");
|
Log.i(TAG, "Updating " + resourcesToUpdate.size() + " remote resource(s)");
|
||||||
if (!resourcesToUpdate.isEmpty())
|
if (!resourcesToUpdate.isEmpty())
|
||||||
for (Resource res : dav.multiGet(resourcesToUpdate.toArray(new Resource[0]))) {
|
for (Resource res : dav.multiGet(resourcesToUpdate.toArray(new Resource[0]))) {
|
||||||
local.updateByRemoteName(res);
|
try {
|
||||||
|
local.updateByRemoteName(res);
|
||||||
|
} catch (ValidationException e) {
|
||||||
|
Log.e(TAG, "Invalid resource: " + res.getName());
|
||||||
|
}
|
||||||
Log.i(TAG, "Updating " + res.getName());
|
Log.i(TAG, "Updating " + res.getName());
|
||||||
syncResult.stats.numInserts++;
|
syncResult.stats.numInserts++;
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ import org.simpleframework.xml.Root;
|
|||||||
@Root(name="calendar-multiget")
|
@Root(name="calendar-multiget")
|
||||||
@NamespaceList({
|
@NamespaceList({
|
||||||
@Namespace(reference="DAV:"),
|
@Namespace(reference="DAV:"),
|
||||||
@Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:caldav")
|
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
|
||||||
})
|
})
|
||||||
@Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:caldav")
|
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
|
||||||
public class DavCalendarMultiget extends DavMultiget {
|
public class DavCalendarMultiget extends DavMultiget {
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,9 @@ public class DavProp {
|
|||||||
@Element(name="address-data",required=false)
|
@Element(name="address-data",required=false)
|
||||||
DavPropAddressData addressData;
|
DavPropAddressData addressData;
|
||||||
|
|
||||||
|
@Element(name="calendar-data",required=false)
|
||||||
|
DavPropCalendarData calendarData;
|
||||||
|
|
||||||
|
|
||||||
public static class DavCurrentUserPrincipal {
|
public static class DavCurrentUserPrincipal {
|
||||||
@Element(required=false)
|
@Element(required=false)
|
||||||
@ -112,4 +115,10 @@ public class DavProp {
|
|||||||
@Text(required=false)
|
@Text(required=false)
|
||||||
@Getter String vcard;
|
@Getter String vcard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Namespace(prefix="C",reference="urn:ietf:params:xml:ns:caldav")
|
||||||
|
public static class DavPropCalendarData {
|
||||||
|
@Text(required=false)
|
||||||
|
@Getter String ical;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class HttpPropfind extends HttpEntityEnclosingRequestBase {
|
|||||||
setHeader("Depth", String.valueOf(depth));
|
setHeader("Depth", String.valueOf(depth));
|
||||||
setEntity(new StringEntity(writer.toString(), "UTF-8"));
|
setEntity(new StringEntity(writer.toString(), "UTF-8"));
|
||||||
|
|
||||||
Log.d(TAG, "Sending PROPFIND request: " + writer.toString());
|
Log.d(TAG, "Prepared PROPFIND request: " + writer.toString());
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
Log.w(TAG, e.getMessage());
|
Log.w(TAG, e.getMessage());
|
||||||
abort();
|
abort();
|
||||||
|
@ -8,11 +8,14 @@
|
|||||||
package at.bitfire.davdroid.webdav;
|
package at.bitfire.davdroid.webdav;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.simpleframework.xml.Serializer;
|
||||||
|
import org.simpleframework.xml.core.Persister;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -26,6 +29,8 @@ public class HttpReport extends HttpEntityEnclosingRequestBase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setEntity(new StringEntity(entity, "UTF-8"));
|
setEntity(new StringEntity(entity, "UTF-8"));
|
||||||
|
|
||||||
|
Log.d(TAG, "Prepared REPORT request: " + entity);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
Log.e(TAG, e.getMessage());
|
Log.e(TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
package at.bitfire.davdroid.webdav;
|
package at.bitfire.davdroid.webdav;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -17,6 +19,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import org.apache.commons.io.input.TeeInputStream;
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
@ -65,9 +68,11 @@ public class WebDavCollection extends WebDavResource {
|
|||||||
DavMultistatus multistatus;
|
DavMultistatus multistatus;
|
||||||
try {
|
try {
|
||||||
Serializer serializer = new Persister();
|
Serializer serializer = new Persister();
|
||||||
multistatus = serializer.read(DavMultistatus.class, response.getEntity().getContent());
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
InputStream is = new TeeInputStream(response.getEntity().getContent(), baos);
|
||||||
|
multistatus = serializer.read(DavMultistatus.class, is);
|
||||||
|
|
||||||
Log.d(TAG, "Got PROPFIND response: " + multistatus.toString());
|
Log.d(TAG, "Received multistatus response: " + baos.toString("UTF-8"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
throw new IncapableResourceException();
|
throw new IncapableResourceException();
|
||||||
@ -80,15 +85,15 @@ public class WebDavCollection extends WebDavResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean multiGet(String[] names, MultigetType type) throws IOException, IncapableResourceException, HttpException {
|
public boolean multiGet(String[] names, MultigetType type) throws IOException, IncapableResourceException, HttpException {
|
||||||
DavMultiget multiget;
|
DavMultiget multiget = (type == MultigetType.ADDRESS_BOOK) ? new DavAddressbookMultiget() : new DavCalendarMultiget();
|
||||||
if (type == MultigetType.ADDRESS_BOOK)
|
|
||||||
multiget = new DavAddressbookMultiget();
|
|
||||||
else // MultigetType.CALENDAR
|
|
||||||
multiget = new DavCalendarMultiget();
|
|
||||||
|
|
||||||
multiget.prop = new DavProp();
|
multiget.prop = new DavProp();
|
||||||
multiget.prop.getetag = new DavProp.DavPropGetETag();
|
multiget.prop.getetag = new DavProp.DavPropGetETag();
|
||||||
multiget.prop.addressData = new DavProp.DavPropAddressData();
|
|
||||||
|
if (type == MultigetType.ADDRESS_BOOK)
|
||||||
|
multiget.prop.addressData = new DavProp.DavPropAddressData();
|
||||||
|
else if (type == MultigetType.CALENDAR)
|
||||||
|
multiget.prop.calendarData = new DavProp.DavPropCalendarData();
|
||||||
|
|
||||||
multiget.hrefs = new ArrayList<DavHref>(names.length);
|
multiget.hrefs = new ArrayList<DavHref>(names.length);
|
||||||
for (String name : names)
|
for (String name : names)
|
||||||
@ -110,7 +115,11 @@ public class WebDavCollection extends WebDavResource {
|
|||||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MULTI_STATUS) {
|
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MULTI_STATUS) {
|
||||||
DavMultistatus multistatus;
|
DavMultistatus multistatus;
|
||||||
try {
|
try {
|
||||||
multistatus = serializer.read(DavMultistatus.class, response.getEntity().getContent());
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
InputStream is = new TeeInputStream(response.getEntity().getContent(), baos);
|
||||||
|
multistatus = serializer.read(DavMultistatus.class, is);
|
||||||
|
|
||||||
|
Log.d(TAG, "Received multistatus response: " + baos.toString("UTF-8"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.getLocalizedMessage());
|
||||||
return false;
|
return false;
|
||||||
@ -208,8 +217,10 @@ public class WebDavCollection extends WebDavResource {
|
|||||||
|
|
||||||
if (prop.getetag != null)
|
if (prop.getetag != null)
|
||||||
referenced.properties.put(Property.ETAG, prop.getetag.getETag());
|
referenced.properties.put(Property.ETAG, prop.getetag.getETag());
|
||||||
|
|
||||||
if (prop.addressData != null)
|
if (prop.calendarData != null)
|
||||||
|
referenced.content = new ByteArrayInputStream(prop.calendarData.ical.getBytes());
|
||||||
|
else if (prop.addressData != null)
|
||||||
referenced.content = new ByteArrayInputStream(prop.addressData.vcard.getBytes());
|
referenced.content = new ByteArrayInputStream(prop.addressData.vcard.getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ package at.bitfire.davdroid.webdav;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -18,6 +20,8 @@ import java.util.Set;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.io.input.TeeInputStream;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
@ -36,10 +40,12 @@ import org.apache.http.impl.EnglishReasonPhraseCatalog;
|
|||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
import org.apache.http.params.CoreProtocolPNames;
|
import org.apache.http.params.CoreProtocolPNames;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
@ToString
|
@ToString
|
||||||
public class WebDavResource {
|
public class WebDavResource {
|
||||||
//private static final String TAG = "davdroid.WebDavResource";
|
private static final String TAG = "davdroid.WebDavResource";
|
||||||
|
|
||||||
public enum Property {
|
public enum Property {
|
||||||
CURRENT_USER_PRINCIPAL,
|
CURRENT_USER_PRINCIPAL,
|
||||||
|
Loading…
Reference in New Issue
Block a user