mirror of
https://github.com/etesync/android
synced 2024-11-22 16:08:13 +00:00
Add more vCard fields
* support for vCard organization (company / job title) * support for vCard IMPP addresses (closes #105) * refactoring
This commit is contained in:
parent
87b71b0b38
commit
8c79c64d75
@ -20,21 +20,35 @@
|
||||
maxOccurs="1" />
|
||||
|
||||
<DataKind kind="phone">
|
||||
<Type type="fax_home" />
|
||||
<Type type="fax_work" />
|
||||
<Type type="home" />
|
||||
<Type type="mobile" />
|
||||
<Type type="other_fax" />
|
||||
<Type type="pager" />
|
||||
<Type type="work" />
|
||||
<Type type="work_mobile" />
|
||||
<Type type="work_pager" />
|
||||
</DataKind>
|
||||
<Type type="mobile" />
|
||||
<Type type="home" />
|
||||
<Type type="work" />
|
||||
<Type type="fax_work" />
|
||||
<Type type="fax_home" />
|
||||
<Type type="pager" />
|
||||
<Type type="other" />
|
||||
<Type type="custom"/>
|
||||
<Type type="callback" />
|
||||
<Type type="car" />
|
||||
<Type type="company_main" />
|
||||
<Type type="isdn" />
|
||||
<Type type="main" />
|
||||
<Type type="other_fax" />
|
||||
<Type type="radio" />
|
||||
<Type type="telex" />
|
||||
<Type type="tty_tdd" />
|
||||
<Type type="work_mobile"/>
|
||||
<Type type="work_pager" />
|
||||
<Type type="assistant" />
|
||||
<Type type="mms" />
|
||||
</DataKind>
|
||||
|
||||
<DataKind kind="email">
|
||||
<Type type="home" />
|
||||
<Type type="work" />
|
||||
<Type type="other" />
|
||||
<Type type="home" />
|
||||
<Type type="work" />
|
||||
<Type type="other" />
|
||||
<Type type="mobile" />
|
||||
<Type type="custom" />
|
||||
</DataKind>
|
||||
|
||||
<DataKind kind="postal" needsStructured="true" >
|
||||
@ -56,10 +70,8 @@
|
||||
<DataKind
|
||||
dateWithTime="false"
|
||||
kind="event">
|
||||
<Type
|
||||
maxOccurs="1"
|
||||
type="birthday"
|
||||
yearOptional="false" />
|
||||
<Type maxOccurs="1" type="birthday" yearOptional="false" />
|
||||
<Type type="anniversary" />
|
||||
</DataKind>
|
||||
</EditSchema>
|
||||
</ContactsAccountType>
|
||||
|
@ -35,11 +35,14 @@ import ezvcard.property.Anniversary;
|
||||
import ezvcard.property.Birthday;
|
||||
import ezvcard.property.Email;
|
||||
import ezvcard.property.FormattedName;
|
||||
import ezvcard.property.Impp;
|
||||
import ezvcard.property.Nickname;
|
||||
import ezvcard.property.Note;
|
||||
import ezvcard.property.Organization;
|
||||
import ezvcard.property.Photo;
|
||||
import ezvcard.property.RawProperty;
|
||||
import ezvcard.property.Revision;
|
||||
import ezvcard.property.Role;
|
||||
import ezvcard.property.StructuredName;
|
||||
import ezvcard.property.Telephone;
|
||||
import ezvcard.property.Uid;
|
||||
@ -71,12 +74,20 @@ 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 note, URL;
|
||||
@Getter @Setter private String organization, role;
|
||||
|
||||
@Getter @Setter private byte[] photo;
|
||||
|
||||
@Getter @Setter private Anniversary anniversary;
|
||||
@Getter @Setter private Birthday birthDay;
|
||||
|
||||
@Getter private List<Email> emails = new LinkedList<Email>();
|
||||
@Getter private List<Telephone> phoneNumbers = new LinkedList<Telephone>();
|
||||
@Getter private List<Address> addresses = new LinkedList<Address>();
|
||||
@Getter private List<Impp> impps = new LinkedList<Impp>();
|
||||
|
||||
|
||||
/* instance methods */
|
||||
|
||||
public Contact(String name, String ETag) {
|
||||
super(name, ETag);
|
||||
@ -87,12 +98,11 @@ public class Contact extends Resource {
|
||||
this.localID = localID;
|
||||
}
|
||||
|
||||
|
||||
/* multiple-record fields */
|
||||
|
||||
@Getter private List<Email> emails = new LinkedList<Email>();
|
||||
@Getter private List<Telephone> phoneNumbers = new LinkedList<Telephone>();
|
||||
@Getter private List<Address> addresses = new LinkedList<Address>();
|
||||
@Override
|
||||
public void initialize() {
|
||||
uid = UUID.randomUUID().toString();
|
||||
name = uid + ".vcf";
|
||||
}
|
||||
|
||||
|
||||
/* VCard methods */
|
||||
@ -155,6 +165,17 @@ public class Contact extends Resource {
|
||||
}
|
||||
}
|
||||
|
||||
if (vcard.getOrganization() != null) {
|
||||
List<String> organizations = vcard.getOrganization().getValues();
|
||||
if (!organizations.isEmpty())
|
||||
organization = organizations.get(0);
|
||||
}
|
||||
List<Role> roles = vcard.getRoles();
|
||||
if (!roles.isEmpty())
|
||||
role = roles.get(0).getValue();
|
||||
|
||||
impps = vcard.getImpps();
|
||||
|
||||
Nickname nicknames = vcard.getNickname();
|
||||
if (nicknames != null && nicknames.getValues() != null)
|
||||
nickName = StringUtils.join(nicknames.getValues(), ", ");
|
||||
@ -221,17 +242,28 @@ public class Contact extends Resource {
|
||||
|
||||
if (photo != null)
|
||||
vcard.addPhoto(new Photo(photo, ImageType.JPEG));
|
||||
|
||||
if (organization != null) {
|
||||
Organization org = new Organization();
|
||||
org.addValue(organization);
|
||||
vcard.addOrganization(org);
|
||||
}
|
||||
if (role != null)
|
||||
vcard.addRole(role);
|
||||
|
||||
for (Impp impp : impps)
|
||||
vcard.addImpp(impp);
|
||||
|
||||
if (nickName != null)
|
||||
if (nickName != null && !nickName.isEmpty())
|
||||
vcard.setNickname(nickName);
|
||||
|
||||
if (note != null)
|
||||
if (note != null && !note.isEmpty())
|
||||
vcard.addNote(note);
|
||||
|
||||
for (Address address : addresses)
|
||||
vcard.addAddress(address);
|
||||
|
||||
if (URL != null)
|
||||
if (URL != null && !URL.isEmpty())
|
||||
vcard.addUrl(URL);
|
||||
|
||||
if (anniversary != null)
|
||||
|
@ -101,6 +101,12 @@ public class Event extends Resource {
|
||||
this(name, ETag);
|
||||
this.localID = localID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
uid = DavSyncAdapter.generateUID();
|
||||
name = uid.replace("@", "_") + ".ics";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -7,11 +7,11 @@
|
||||
******************************************************************************/
|
||||
package at.bitfire.davdroid.resource;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
@ -28,8 +28,10 @@ import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.ContactsContract.CommonDataKinds;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Im;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Nickname;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Note;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Organization;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
@ -40,16 +42,18 @@ import android.provider.ContactsContract.RawContacts;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import ezvcard.parameter.AddressType;
|
||||
import ezvcard.parameter.EmailType;
|
||||
import ezvcard.parameter.ImppType;
|
||||
import ezvcard.parameter.TelephoneType;
|
||||
import ezvcard.property.Address;
|
||||
import ezvcard.property.Anniversary;
|
||||
import ezvcard.property.Birthday;
|
||||
import ezvcard.property.DateOrTimeProperty;
|
||||
import ezvcard.property.Impp;
|
||||
import ezvcard.property.Telephone;
|
||||
|
||||
|
||||
public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
private final static String TAG = "davdroid.LocalAddressBook";
|
||||
//private final static String TAG = "davdroid.LocalAddressBook";
|
||||
|
||||
protected AccountManager accountManager;
|
||||
|
||||
@ -101,25 +105,6 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
|
||||
|
||||
/* content provider (= database) querying */
|
||||
|
||||
@Override
|
||||
public Contact findById(long localID, String remoteName, String eTag, boolean populate) throws RemoteException {
|
||||
Contact c = new Contact(localID, remoteName, eTag);
|
||||
if (populate)
|
||||
populate(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Contact findByRemoteName(String remoteName) throws RemoteException {
|
||||
Cursor cursor = providerClient.query(entriesURI(),
|
||||
new String[] { RawContacts._ID, entryColumnRemoteName(), entryColumnETag() },
|
||||
entryColumnRemoteName() + "=?", new String[] { remoteName }, null);
|
||||
if (cursor != null && cursor.moveToNext())
|
||||
return new Contact(cursor.getLong(0), cursor.getString(1), cursor.getString(2));
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(Resource res) throws RemoteException {
|
||||
@ -254,11 +239,77 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
|
||||
// photo
|
||||
cursor = providerClient.query(dataURI(), new String[] { Photo.PHOTO },
|
||||
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||
new String[] { String.valueOf(c.getLocalID()), Photo.CONTENT_ITEM_TYPE }, null);
|
||||
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||
new String[] { String.valueOf(c.getLocalID()), Photo.CONTENT_ITEM_TYPE }, null);
|
||||
if (cursor != null && cursor.moveToNext())
|
||||
c.setPhoto(cursor.getBlob(0));
|
||||
|
||||
// organization
|
||||
cursor = providerClient.query(dataURI(), new String[] { Organization.COMPANY, Organization.TITLE },
|
||||
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||
new String[] { String.valueOf(c.getLocalID()), Organization.CONTENT_ITEM_TYPE }, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
c.setOrganization(cursor.getString(0));
|
||||
c.setRole(cursor.getString(1));
|
||||
}
|
||||
|
||||
// IMPPs
|
||||
cursor = providerClient.query(dataURI(), new String[] { Im.DATA, Im.TYPE, Im.LABEL, Im.PROTOCOL, Im.CUSTOM_PROTOCOL },
|
||||
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||
new String[] { String.valueOf(c.getLocalID()), Im.CONTENT_ITEM_TYPE }, null);
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String handle = cursor.getString(0);
|
||||
|
||||
Impp impp = null;
|
||||
switch (cursor.getInt(3)) {
|
||||
case Im.PROTOCOL_AIM:
|
||||
impp = Impp.aim(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_MSN:
|
||||
impp = Impp.msn(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_YAHOO:
|
||||
impp = Impp.yahoo(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_SKYPE:
|
||||
impp = Impp.skype(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_QQ:
|
||||
impp = new Impp("qq", handle);
|
||||
break;
|
||||
case Im.PROTOCOL_GOOGLE_TALK:
|
||||
impp = new Impp("google-talk", handle);
|
||||
break;
|
||||
case Im.PROTOCOL_ICQ:
|
||||
impp = Impp.icq(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_JABBER:
|
||||
impp = Impp.xmpp(handle);
|
||||
break;
|
||||
case Im.PROTOCOL_NETMEETING:
|
||||
impp = new Impp("netmeeting", handle);
|
||||
break;
|
||||
case Im.PROTOCOL_CUSTOM:
|
||||
impp = new Impp(cursor.getString(4), handle);
|
||||
break;
|
||||
}
|
||||
|
||||
if (impp != null) {
|
||||
switch (cursor.getInt(1)) {
|
||||
case Im.TYPE_HOME:
|
||||
impp.addType(ImppType.HOME);
|
||||
break;
|
||||
case Im.TYPE_WORK:
|
||||
impp.addType(ImppType.WORK);
|
||||
break;
|
||||
case Im.TYPE_CUSTOM:
|
||||
impp.addType(ImppType.get(labelToXName(cursor.getString(2))));
|
||||
break;
|
||||
}
|
||||
c.getImpps().add(impp);
|
||||
}
|
||||
}
|
||||
|
||||
// nick name (max. 1)
|
||||
cursor = providerClient.query(dataURI(), new String[] { Nickname.NAME },
|
||||
Nickname.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||
@ -348,20 +399,17 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
.withYieldAllowed(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
/* create/update/delete */
|
||||
|
||||
public Contact newResource(long localID, String resourceName, String eTag) {
|
||||
return new Contact(localID, resourceName, eTag);
|
||||
}
|
||||
|
||||
|
||||
/* private helper methods */
|
||||
|
||||
@Override
|
||||
protected String fileExtension() {
|
||||
return ".vcf";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String randomUID() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
protected Uri dataURI() {
|
||||
return syncAdapterURI(Data.CONTENT_URI);
|
||||
}
|
||||
@ -416,8 +464,11 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
if (contact.getPhoto() != null)
|
||||
pendingOperations.add(buildPhoto(newDataInsertBuilder(localID, backrefIdx), contact.getPhoto()).build());
|
||||
|
||||
// TODO organization
|
||||
// TODO im
|
||||
if (contact.getOrganization() != null || contact.getRole() != null)
|
||||
pendingOperations.add(buildOrganization(newDataInsertBuilder(localID, backrefIdx), contact.getOrganization(), contact.getRole()).build());
|
||||
|
||||
for (Impp impp : contact.getImpps())
|
||||
pendingOperations.add(buildIMPP(newDataInsertBuilder(localID, backrefIdx), impp).build());
|
||||
|
||||
if (contact.getNickName() != null)
|
||||
pendingOperations.add(buildNickName(newDataInsertBuilder(localID, backrefIdx), contact.getNickName()).build());
|
||||
@ -530,7 +581,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
}
|
||||
|
||||
protected Builder buildEmail(Builder builder, ezvcard.property.Email email) {
|
||||
int typeCode = Email.TYPE_OTHER;
|
||||
int typeCode = 0;
|
||||
String typeLabel = null;
|
||||
|
||||
for (EmailType type : email.getTypes())
|
||||
@ -540,10 +591,14 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
typeCode = Email.TYPE_WORK;
|
||||
else if (type == Contact.EMAIL_TYPE_MOBILE)
|
||||
typeCode = Email.TYPE_MOBILE;
|
||||
if (typeCode == 0) {
|
||||
if (email.getTypes().isEmpty())
|
||||
typeCode = Email.TYPE_OTHER;
|
||||
else {
|
||||
typeCode = Email.TYPE_CUSTOM;
|
||||
typeLabel = xNameToLabel(type.getValue());
|
||||
typeLabel = xNameToLabel(email.getTypes().iterator().next().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
builder = builder
|
||||
.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
|
||||
@ -560,6 +615,69 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
.withValue(Photo.PHOTO, photo);
|
||||
}
|
||||
|
||||
protected Builder buildOrganization(Builder builder, String organization, String role) {
|
||||
return builder
|
||||
.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE)
|
||||
.withValue(Organization.COMPANY, organization)
|
||||
.withValue(Organization.TITLE, role);
|
||||
}
|
||||
|
||||
protected Builder buildIMPP(Builder builder, Impp impp) {
|
||||
int typeCode = 0;
|
||||
String typeLabel = null;
|
||||
for (ImppType type : impp.getTypes())
|
||||
if (type == ImppType.HOME)
|
||||
typeCode = Im.TYPE_HOME;
|
||||
else if (type == ImppType.WORK || type == ImppType.BUSINESS)
|
||||
typeCode = Im.TYPE_WORK;
|
||||
if (typeCode == 0)
|
||||
if (impp.getTypes().isEmpty())
|
||||
typeCode = Im.TYPE_OTHER;
|
||||
else {
|
||||
typeCode = Im.TYPE_CUSTOM;
|
||||
typeLabel = xNameToLabel(impp.getTypes().iterator().next().getValue());
|
||||
}
|
||||
|
||||
int protocolCode;
|
||||
String protocolLabel = null;
|
||||
if (impp.isAim())
|
||||
protocolCode = Im.PROTOCOL_AIM;
|
||||
else if (impp.isMsn())
|
||||
protocolCode = Im.PROTOCOL_MSN;
|
||||
else if (impp.isYahoo())
|
||||
protocolCode = Im.PROTOCOL_YAHOO;
|
||||
else if (impp.isSkype())
|
||||
protocolCode = Im.PROTOCOL_SKYPE;
|
||||
else if (impp.getProtocol().equalsIgnoreCase("qq"))
|
||||
protocolCode = Im.PROTOCOL_QQ;
|
||||
else if (impp.getProtocol().equalsIgnoreCase("google-talk"))
|
||||
protocolCode = Im.PROTOCOL_GOOGLE_TALK;
|
||||
else if (impp.isIcq())
|
||||
protocolCode = Im.PROTOCOL_ICQ;
|
||||
else if (impp.isXmpp())
|
||||
protocolCode = Im.PROTOCOL_JABBER;
|
||||
else if (impp.getProtocol().equalsIgnoreCase("netmeeting"))
|
||||
protocolCode = Im.PROTOCOL_NETMEETING;
|
||||
else {
|
||||
String protocol = impp.getProtocol();
|
||||
if (protocol == null)
|
||||
protocol = "unknown";
|
||||
protocolCode = Im.PROTOCOL_CUSTOM;
|
||||
protocolLabel = protocol;
|
||||
}
|
||||
|
||||
builder = builder
|
||||
.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE)
|
||||
.withValue(Im.DATA, impp.getHandle())
|
||||
.withValue(Im.TYPE, typeCode)
|
||||
.withValue(Im.PROTOCOL, protocolCode);
|
||||
if (typeLabel != null)
|
||||
builder = builder.withValue(Im.LABEL, typeLabel);
|
||||
if (protocolLabel != null)
|
||||
builder = builder.withValue(Im.CUSTOM_PROTOCOL, protocolLabel);
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected Builder buildNickName(Builder builder, String nickName) {
|
||||
return builder
|
||||
.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE)
|
||||
@ -594,16 +712,19 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
formattedAddress = StringUtils.join(lines, "\n");
|
||||
}
|
||||
|
||||
int typeCode = StructuredPostal.TYPE_OTHER;
|
||||
int typeCode = 0;
|
||||
String typeLabel = null;
|
||||
for (AddressType type : address.getTypes())
|
||||
if (type == AddressType.HOME)
|
||||
typeCode = StructuredPostal.TYPE_HOME;
|
||||
else if (type == AddressType.WORK)
|
||||
typeCode = StructuredPostal.TYPE_WORK;
|
||||
if (typeCode == 0)
|
||||
if (address.getTypes().isEmpty())
|
||||
typeCode = StructuredPostal.TYPE_OTHER;
|
||||
else {
|
||||
typeCode = StructuredPostal.TYPE_CUSTOM;
|
||||
typeLabel = xNameToLabel(type.getValue());
|
||||
typeLabel = xNameToLabel(address.getTypes().iterator().next().getValue());
|
||||
}
|
||||
|
||||
builder = builder
|
||||
@ -629,9 +750,10 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
||||
}
|
||||
|
||||
protected Builder buildEvent(Builder builder, DateOrTimeProperty date, int type) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||
return builder
|
||||
.withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE)
|
||||
.withValue(CommonDataKinds.Event.TYPE, type)
|
||||
.withValue(CommonDataKinds.Event.START_DATE, date.getText());
|
||||
.withValue(CommonDataKinds.Event.START_DATE, formatter.format(date.getDate()));
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,6 @@ import android.provider.CalendarContract.Events;
|
||||
import android.provider.CalendarContract.Reminders;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import at.bitfire.davdroid.syncadapter.DavSyncAdapter;
|
||||
import at.bitfire.davdroid.syncadapter.ServerInfo;
|
||||
|
||||
public class LocalCalendar extends LocalCollection<Event> {
|
||||
@ -167,26 +166,6 @@ public class LocalCalendar extends LocalCollection<Event> {
|
||||
|
||||
|
||||
/* content provider (= database) querying */
|
||||
|
||||
@Override
|
||||
public Event findById(long localID, String remoteName, String eTag, boolean populate) throws RemoteException {
|
||||
Event e = new Event(localID, remoteName, eTag);
|
||||
if (populate)
|
||||
populate(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event findByRemoteName(String remoteName) throws RemoteException {
|
||||
Cursor cursor = providerClient.query(entriesURI(),
|
||||
new String[] { entryColumnID(), entryColumnRemoteName(), entryColumnETag() },
|
||||
Events.CALENDAR_ID + "=? AND " + entryColumnRemoteName() + "=?",
|
||||
new String[] { String.valueOf(id), remoteName }, null);
|
||||
if (cursor != null && cursor.moveToNext())
|
||||
return new Event(cursor.getLong(0), cursor.getString(1), cursor.getString(2));
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(Resource resource) throws RemoteException {
|
||||
@ -398,18 +377,15 @@ public class LocalCalendar extends LocalCollection<Event> {
|
||||
}
|
||||
|
||||
|
||||
/* create/update/delete */
|
||||
|
||||
public Event newResource(long localID, String resourceName, String eTag) {
|
||||
return new Event(localID, resourceName, eTag);
|
||||
}
|
||||
|
||||
|
||||
/* private helper methods */
|
||||
|
||||
@Override
|
||||
protected String fileExtension() {
|
||||
return ".ics";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String randomUID() {
|
||||
return DavSyncAdapter.generateUID();
|
||||
}
|
||||
|
||||
protected static Uri calendarsURI(Account account) {
|
||||
return Calendars.CONTENT_URI.buildUpon().appendQueryParameter(Calendars.ACCOUNT_NAME, account.name)
|
||||
.appendQueryParameter(Calendars.ACCOUNT_TYPE, account.type)
|
||||
|
@ -80,7 +80,7 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
where, null, null);
|
||||
LinkedList<T> dirty = new LinkedList<T>();
|
||||
while (cursor != null && cursor.moveToNext())
|
||||
dirty.add(findById(cursor.getLong(0), cursor.getString(1), cursor.getString(2), true));
|
||||
dirty.add(findById(cursor.getLong(0), true));
|
||||
return dirty.toArray(new Resource[0]);
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
where, null, null);
|
||||
LinkedList<T> deleted = new LinkedList<T>();
|
||||
while (cursor != null && cursor.moveToNext())
|
||||
deleted.add(findById(cursor.getLong(0), cursor.getString(1), cursor.getString(2), false));
|
||||
deleted.add(findById(cursor.getLong(0), false));
|
||||
return deleted.toArray(new Resource[0]);
|
||||
}
|
||||
|
||||
@ -106,15 +106,17 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
where, null, null);
|
||||
LinkedList<T> fresh = new LinkedList<T>();
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String uid = randomUID(),
|
||||
resourceName = uid.replace("@", "_") + fileExtension();
|
||||
T resource = findById(cursor.getLong(0), resourceName, null, true);
|
||||
resource.setUid(uid);
|
||||
T resource = findById(cursor.getLong(0), true);
|
||||
/*String uid = randomUID(),
|
||||
resourceName = uid.replace("@", "_") + fileExtension();
|
||||
resource.setUid(uid);*/
|
||||
resource.initialize();
|
||||
|
||||
// new record: set generated UID + remote file name in database
|
||||
pendingOperations.add(ContentProviderOperation
|
||||
.newUpdate(ContentUris.withAppendedId(entriesURI(), resource.getLocalID()))
|
||||
.withValue(entryColumnRemoteName(), resourceName)
|
||||
.withValue(entryColumnUID(), resource.getUid())
|
||||
.withValue(entryColumnRemoteName(), resource.getName())
|
||||
.build());
|
||||
|
||||
fresh.add(resource);
|
||||
@ -122,14 +124,39 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
return fresh.toArray(new Resource[0]);
|
||||
}
|
||||
|
||||
abstract public T findById(long localID, String resourceName, String eTag, boolean populate) throws RemoteException;
|
||||
abstract public T findByRemoteName(String name) throws RemoteException;
|
||||
public T findById(long localID, boolean populate) throws RemoteException {
|
||||
Cursor cursor = providerClient.query(ContentUris.withAppendedId(entriesURI(), localID),
|
||||
new String[] { entryColumnRemoteName(), entryColumnETag() }, null, null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
T resource = newResource(localID, cursor.getString(0), cursor.getString(1));
|
||||
if (populate)
|
||||
populate(resource);
|
||||
return resource;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
public T findByRemoteName(String remoteName, boolean populate) throws RemoteException {
|
||||
Cursor cursor = providerClient.query(entriesURI(),
|
||||
new String[] { entryColumnID(), entryColumnRemoteName(), entryColumnETag() },
|
||||
entryColumnRemoteName() + "=?", new String[] { remoteName }, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
T resource = newResource(cursor.getLong(0), cursor.getString(1), cursor.getString(2));
|
||||
if (populate)
|
||||
populate(resource);
|
||||
return resource;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public abstract void populate(Resource record) throws RemoteException;
|
||||
|
||||
|
||||
// create/update/delete
|
||||
|
||||
abstract public T newResource(long localID, String resourceName, String eTag);
|
||||
|
||||
public void add(Resource resource) {
|
||||
int idx = pendingOperations.size();
|
||||
pendingOperations.add(
|
||||
@ -141,7 +168,7 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
}
|
||||
|
||||
public void updateByRemoteName(Resource remoteResource) throws RemoteException, ValidationException {
|
||||
T localResource = findByRemoteName(remoteResource.getName());
|
||||
T localResource = findByRemoteName(remoteResource.getName(), false);
|
||||
|
||||
pendingOperations.add(
|
||||
buildEntry(ContentProviderOperation.newUpdate(ContentUris.withAppendedId(entriesURI(), localResource.getLocalID())), remoteResource)
|
||||
@ -179,10 +206,6 @@ public abstract class LocalCollection<T extends Resource> {
|
||||
|
||||
// helpers
|
||||
|
||||
protected abstract String fileExtension();
|
||||
|
||||
protected abstract String randomUID();
|
||||
|
||||
protected Uri syncAdapterURI(Uri baseURI) {
|
||||
return baseURI.buildUpon()
|
||||
.appendQueryParameter(entryColumnAccountType(), account.type)
|
||||
|
@ -36,6 +36,9 @@ public abstract class Resource {
|
||||
this.localID = localID;
|
||||
}
|
||||
|
||||
// sets resource name and UID
|
||||
public abstract void initialize();
|
||||
|
||||
public abstract void parseEntity(InputStream entity) throws IOException, ParserException, VCardException;
|
||||
public abstract String toEntity() throws IOException, ValidationException;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ public class SyncManager {
|
||||
return;
|
||||
|
||||
for (Resource remoteResource : remoteResources) {
|
||||
Resource localResource = local.findByRemoteName(remoteResource.getName());
|
||||
Resource localResource = local.findByRemoteName(remoteResource.getName(), true);
|
||||
if (localResource == null)
|
||||
resourcesToAdd.add(remoteResource);
|
||||
else if (localResource.getETag() == null || !localResource.getETag().equals(remoteResource.getETag()))
|
||||
|
Loading…
Reference in New Issue
Block a user