From ff4fe77fe3e69d054cce4a03a8f344cbb4a226ec Mon Sep 17 00:00:00 2001 From: rfc2822 Date: Fri, 1 Nov 2013 12:13:45 +0100 Subject: [PATCH] improved photo parsing, DELETE statement * let ical4l-vcard do the photo parsing; tested with posteo, OwnCloud, eM Client; fixes #53 * improved DELETE statement to avoid "android.database.sqlite.SQLiteException: Expression tree is too large" (fixes #54) * added "file name required" validation --- src/at/bitfire/davdroid/resource/Contact.java | 60 +++---------------- src/at/bitfire/davdroid/resource/Event.java | 4 +- .../davdroid/resource/LocalAddressBook.java | 6 +- .../davdroid/resource/LocalCalendar.java | 6 +- .../bitfire/davdroid/resource/Resource.java | 4 +- 5 files changed, 19 insertions(+), 61 deletions(-) diff --git a/src/at/bitfire/davdroid/resource/Contact.java b/src/at/bitfire/davdroid/resource/Contact.java index 9a6c7000..a8c82b82 100644 --- a/src/at/bitfire/davdroid/resource/Contact.java +++ b/src/at/bitfire/davdroid/resource/Contact.java @@ -11,11 +11,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -34,6 +31,7 @@ import net.fortuna.ical4j.vcard.PropertyFactoryRegistry; import net.fortuna.ical4j.vcard.VCard; import net.fortuna.ical4j.vcard.VCardBuilder; import net.fortuna.ical4j.vcard.VCardOutputter; +import net.fortuna.ical4j.vcard.parameter.Type; import net.fortuna.ical4j.vcard.property.BDay; import net.fortuna.ical4j.vcard.property.Email; import net.fortuna.ical4j.vcard.property.Fn; @@ -46,10 +44,8 @@ import net.fortuna.ical4j.vcard.property.Uid; import net.fortuna.ical4j.vcard.property.Url; import net.fortuna.ical4j.vcard.property.Version; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import android.util.Base64; import android.util.Log; import at.bitfire.davdroid.ical4j.PhoneticFirstName; import at.bitfire.davdroid.ical4j.PhoneticLastName; @@ -183,30 +179,8 @@ public class Contact extends Resource { phoneNumbers.add((Telephone)p); Photo photo = (Photo)vcard.getProperty(Id.PHOTO); - if (photo != null) { - if (photo.getBinary() != null) - this.photo = photo.getBinary(); - else if (photo.getUri() != null) { - URI uri = photo.getUri(); - try { - if (uri.getScheme().equalsIgnoreCase("data")) - this.photo = parseDataURI(uri); - else { - URL url = photo.getUri().toURL(); - HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); - try { - this.photo = IOUtils.toByteArray(urlConnection.getInputStream()); - } finally { - urlConnection.disconnect(); - } - } - } catch(MalformedURLException ex) { - Log.w(TAG, "Malformed photo URL given in VCard"); - } catch(IOException ex) { - Log.w(TAG, "Couldn't download photo from URL given in VCard"); - } - } - } + if (photo != null) + this.photo = photo.getBinary(); for (Property p : vcard.getProperties(Id.BDAY)) birthDay = ((BDay)p).getDate(); @@ -242,14 +216,9 @@ public class Contact extends Resource { if (nickNames != null) properties.add(new Nickname(nickNames)); - if (photo != null) { - try { - String base64 = Base64.encodeToString(photo, Base64.NO_WRAP); - properties.add(new Photo(new URI("data", "image/jpeg;base64," + base64, null))); - } catch (URISyntaxException e) { - Log.w(TAG, "Couldn't encode photo"); - } - } + if (photo != null) + properties.add(new Photo(photo, new Type("image/jpeg"))); + Log.d(TAG, new Photo(photo, new Type("image/jpeg")).toString()); if (birthDay != null) properties.add(new BDay(birthDay)); @@ -282,24 +251,9 @@ public class Contact extends Resource { return writer.toString(); } - - protected byte[] parseDataURI(URI uri) throws MalformedURLException { - String content = uri.getSchemeSpecificPart(); - - int commaPos = content.indexOf(','); - if (commaPos == -1) - throw new MalformedURLException("Malformed data: URL"); - - String header = content.substring(0, commaPos); - String data = content.substring(commaPos + 1); - - if (header.endsWith(";base64")) - return Base64.decode(data, Base64.DEFAULT); - - return null; - } @Override public void validate() throws ValidationException { + super.validate(); } } diff --git a/src/at/bitfire/davdroid/resource/Event.java b/src/at/bitfire/davdroid/resource/Event.java index bb31954e..54af7739 100644 --- a/src/at/bitfire/davdroid/resource/Event.java +++ b/src/at/bitfire/davdroid/resource/Event.java @@ -301,7 +301,9 @@ public class Event extends Resource { @Override public void validate() throws ValidationException { + super.validate(); + if (dtStart == null) - throw new ValidationException("dtStart empty"); + throw new ValidationException("dtStart must not be empty"); } } diff --git a/src/at/bitfire/davdroid/resource/LocalAddressBook.java b/src/at/bitfire/davdroid/resource/LocalAddressBook.java index 6cb8e279..b734603f 100644 --- a/src/at/bitfire/davdroid/resource/LocalAddressBook.java +++ b/src/at/bitfire/davdroid/resource/LocalAddressBook.java @@ -272,10 +272,10 @@ public class LocalAddressBook extends LocalCollection { String where; if (remoteResources.length != 0) { - List terms = new LinkedList(); + List sqlFileNames = new LinkedList(); for (Resource res : remoteResources) - terms.add(entryColumnRemoteName() + "<>" + DatabaseUtils.sqlEscapeString(res.getName())); - where = StringUtils.join(terms, " AND "); + sqlFileNames.add(DatabaseUtils.sqlEscapeString(res.getName())); + where = entryColumnRemoteName() + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")"; } else where = entryColumnRemoteName() + " IS NOT NULL"; diff --git a/src/at/bitfire/davdroid/resource/LocalCalendar.java b/src/at/bitfire/davdroid/resource/LocalCalendar.java index ec883cb1..8aef809e 100644 --- a/src/at/bitfire/davdroid/resource/LocalCalendar.java +++ b/src/at/bitfire/davdroid/resource/LocalCalendar.java @@ -330,10 +330,10 @@ public class LocalCalendar extends LocalCollection { String where; if (remoteResources.length != 0) { - List terms = new LinkedList(); + List sqlFileNames = new LinkedList(); for (Resource res : remoteResources) - terms.add(entryColumnRemoteName() + "<>" + DatabaseUtils.sqlEscapeString(res.getName())); - where = StringUtils.join(terms, " AND "); + sqlFileNames.add(DatabaseUtils.sqlEscapeString(res.getName())); + where = entryColumnRemoteName() + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")"; } else where = entryColumnRemoteName() + " IS NOT NULL"; diff --git a/src/at/bitfire/davdroid/resource/Resource.java b/src/at/bitfire/davdroid/resource/Resource.java index c1726161..501702f8 100644 --- a/src/at/bitfire/davdroid/resource/Resource.java +++ b/src/at/bitfire/davdroid/resource/Resource.java @@ -39,5 +39,7 @@ public abstract class Resource { public abstract void parseEntity(InputStream entity) throws IOException, ParserException; public abstract String toEntity() throws IOException, ValidationException; - public abstract void validate() throws ValidationException; + public void validate() throws ValidationException { + if (name == null) throw new ValidationException("File name must be set"); + } }