support for structured addresses (closes #29); bug fixes

pull/2/head
rfc2822 11 years ago
parent fb671a67a4
commit 603758fcbc

@ -37,6 +37,13 @@
<Type type="other" />
</DataKind>
<DataKind kind="postal" needsStructured="true" >
<Type type="home" />
<Type type="work" />
<Type type="other" />
<Type type="custom" />
</DataKind>
<DataKind
kind="nickname"
maxOccurs="1" />

@ -23,7 +23,6 @@ import lombok.ToString;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.ValidationException;
import net.fortuna.ical4j.util.CompatibilityHints;
import net.fortuna.ical4j.vcard.GroupRegistry;
import net.fortuna.ical4j.vcard.ParameterFactoryRegistry;
import net.fortuna.ical4j.vcard.Property;
@ -33,6 +32,7 @@ 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.Address;
import net.fortuna.ical4j.vcard.property.BDay;
import net.fortuna.ical4j.vcard.property.Email;
import net.fortuna.ical4j.vcard.property.Fn;
@ -45,7 +45,6 @@ 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.Log;
@ -64,7 +63,7 @@ public class Contact extends Resource {
@Getter @Setter private String prefix, givenName, middleName, familyName, suffix;
@Getter @Setter private String phoneticGivenName, phoneticMiddleName, phoneticFamilyName;
@Getter @Setter private String[] nickNames;
@Getter @Setter private byte[] photo;
@Getter @Setter private Date birthDay;
@ -92,6 +91,11 @@ public class Contact extends Resource {
phoneNumbers.add(number);
}
@Getter private List<Address> addresses = new LinkedList<Address>();
public void addAddress(Address address) {
addresses.add(address);
}
@Getter private List<URI> URLs = new LinkedList<URI>();
public void addURL(URI url) {
URLs.add(url);
@ -118,8 +122,6 @@ public class Contact extends Resource {
propertyFactoryRegistry.register("X-" + PhoneticMiddleName.PROPERTY_NAME, new PhoneticMiddleName.Factory());
propertyFactoryRegistry.register("X-" + PhoneticLastName.PROPERTY_NAME, new PhoneticLastName.Factory());
//Log.d(TAG, IOUtils.toString(is));
VCardBuilder builder = new VCardBuilder(
new InputStreamReader(is),
new GroupRegistry(),
@ -155,7 +157,6 @@ public class Contact extends Resource {
if (nickname != null)
nickNames = nickname.getNames();
// structured name
N n = (N)vcard.getProperty(Id.N);
if (n != null) {
prefix = StringUtils.join(n.getPrefixes(), " ");
@ -165,7 +166,6 @@ public class Contact extends Resource {
suffix = StringUtils.join(n.getSuffixes(), " ");
}
// phonetic name
PhoneticFirstName phoneticFirstName = (PhoneticFirstName)vcard.getExtendedProperty(PhoneticFirstName.PROPERTY_NAME);
if (phoneticFirstName != null)
phoneticGivenName = phoneticFirstName.getValue();
@ -182,6 +182,9 @@ public class Contact extends Resource {
for (Property p : vcard.getProperties(Id.TEL))
phoneNumbers.add((Telephone)p);
for (Property p : vcard.getProperties(Id.ADR))
addresses.add((Address)p);
Photo photo = (Photo)vcard.getProperty(Id.PHOTO);
if (photo != null)
this.photo = photo.getBinary();
@ -236,12 +239,15 @@ public class Contact extends Resource {
properties.add(new PhoneticMiddleName(phoneticMiddleName));
if (phoneticFamilyName != null)
properties.add(new PhoneticLastName(phoneticFamilyName));
if (!emails.isEmpty())
properties.addAll(emails);
if (!addresses.isEmpty())
properties.addAll(addresses);
for (Email email : emails)
properties.add(email);
for (Telephone number : phoneNumbers)
properties.add(number);
if (!phoneNumbers.isEmpty())
properties.addAll(phoneNumbers);
for (URI uri : URLs)
properties.add(new Url(uri));

@ -16,6 +16,7 @@ import java.util.List;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.vcard.Parameter.Id;
import net.fortuna.ical4j.vcard.parameter.Type;
import net.fortuna.ical4j.vcard.property.Address;
import net.fortuna.ical4j.vcard.property.Telephone;
import org.apache.commons.lang.StringUtils;
@ -37,6 +38,7 @@ import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
@ -223,6 +225,32 @@ public class LocalAddressBook extends LocalCollection<Contact> {
c.addPhoneNumber(number);
}
// postal addresses
cursor = providerClient.query(dataURI(), new String[] {
/* 0 */ StructuredPostal.FORMATTED_ADDRESS, StructuredPostal.TYPE,
/* 2 */ StructuredPostal.STREET, StructuredPostal.POBOX, StructuredPostal.NEIGHBORHOOD,
/* 5 */ StructuredPostal.CITY, StructuredPostal.REGION, StructuredPostal.POSTCODE,
/* 8 */ StructuredPostal.COUNTRY
}, StructuredPostal.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
new String[] { String.valueOf(c.getLocalID()), StructuredPostal.CONTENT_ITEM_TYPE }, null);
while (cursor != null && cursor.moveToNext()) {
Type[] types = new Type[] {};
switch (cursor.getInt(1)) {
case StructuredPostal.TYPE_HOME:
types = new Type[] { Type.HOME };
break;
case StructuredPostal.TYPE_WORK:
types = new Type[] { Type.WORK };
break;
}
Address address = new Address(
cursor.getString(3), cursor.getString(4), cursor.getString(2),
cursor.getString(5), cursor.getString(6), cursor.getString(7),
cursor.getString(8), types
);
c.addAddress(address);
}
// photo
cursor = providerClient.query(dataURI(), new String[] { Photo.PHOTO },
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
@ -329,6 +357,9 @@ public class LocalAddressBook extends LocalCollection<Contact> {
for (Telephone number : contact.getPhoneNumbers())
pendingOperations.add(buildPhoneNumber(newDataInsertBuilder(localID, backrefIdx), number).build());
for (Address address : contact.getAddresses())
pendingOperations.add(buildAddress(newDataInsertBuilder(localID, backrefIdx), address).build());
if (contact.getPhoto() != null)
pendingOperations.add(buildPhoto(newDataInsertBuilder(localID, backrefIdx), contact.getPhoto()).build());
@ -444,6 +475,43 @@ public class LocalAddressBook extends LocalCollection<Contact> {
.withValue(Phone.TYPE, type);
}
protected Builder buildAddress(Builder builder, Address address) {
/* street po.box (extended)
* region
* postal code city
* country
*/
String lineStreet = StringUtils.join(new String[] { address.getStreet(), address.getPoBox(), address.getExtended() }, " "),
lineLocality = StringUtils.join(new String[] { address.getPostcode(), address.getLocality() }, " ");
List<String> lines = new LinkedList<String>();
if (lineStreet != null)
lines.add(lineStreet);
if (address.getRegion() != null && !address.getRegion().isEmpty())
lines.add(address.getRegion());
if (lineLocality != null)
lines.add(lineLocality);
int typeCode = StructuredPostal.TYPE_OTHER;
Type type = (Type)address.getParameter(Id.TYPE);
if (type == Type.HOME)
typeCode = StructuredPostal.TYPE_HOME;
else if (type == Type.WORK)
typeCode = StructuredPostal.TYPE_WORK;
return builder
.withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(StructuredPostal.FORMATTED_ADDRESS, StringUtils.join(lines, "\n"))
.withValue(StructuredPostal.TYPE, typeCode)
.withValue(StructuredPostal.STREET, address.getStreet())
.withValue(StructuredPostal.POBOX, address.getPoBox())
.withValue(StructuredPostal.NEIGHBORHOOD, address.getExtended())
.withValue(StructuredPostal.CITY, address.getLocality())
.withValue(StructuredPostal.REGION, address.getRegion())
.withValue(StructuredPostal.POSTCODE, address.getPostcode())
.withValue(StructuredPostal.COUNTRY, address.getCountry());
}
protected Builder buildPhoto(Builder builder, byte[] photo) {
return builder
.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE)

@ -8,6 +8,7 @@
package at.bitfire.davdroid.resource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
@ -80,8 +81,12 @@ public abstract class RemoteCollection<ResourceType extends Resource> {
for (WebDavResource member : collection.getMembers()) {
ResourceType resource = newResourceSkeleton(member.getName(), member.getETag());
try {
resource.parseEntity(member.getContent());
foundResources.add(resource);
InputStream is = member.getContent();
if (is != null) {
resource.parseEntity(is);
foundResources.add(resource);
} else
Log.e(TAG, "Ignoring entity without content");
} catch (ParserException ex) {
Log.e(TAG, "Ignoring unparseable entity in multi-response", ex);
}

@ -140,12 +140,14 @@ public class WebDavResource {
checkResponse(response);
Header[] allowHeaders = response.getHeaders("Allow");
for (Header allowHeader : allowHeaders)
methods.addAll(Arrays.asList(allowHeader.getValue().split(", ?")));
if (allowHeaders != null)
for (Header allowHeader : allowHeaders)
methods.addAll(Arrays.asList(allowHeader.getValue().split(", ?")));
Header[] capHeaders = response.getHeaders("DAV");
for (Header capHeader : capHeaders)
capabilities.addAll(Arrays.asList(capHeader.getValue().split(", ?")));
if (capHeaders != null)
for (Header capHeader : capHeaders)
capabilities.addAll(Arrays.asList(capHeader.getValue().split(", ?")));
}
public boolean supportsDAV(String capability) {

Loading…
Cancel
Save