mirror of
https://github.com/etesync/android
synced 2024-12-24 07:28:09 +00:00
Minor refactoring
* update target SDK version to API level 19 * less null return values * explicit Resource generateUID/generateName methods * use StringUtils when it makes sense
This commit is contained in:
parent
df012efe78
commit
8be6fdedd9
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="14"
|
android:minSdkVersion="14"
|
||||||
android:targetSdkVersion="17" />
|
android:targetSdkVersion="19" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||||
|
@ -10,9 +10,6 @@ public class URIUtils {
|
|||||||
|
|
||||||
// handles invalid URLs/paths as good as possible
|
// handles invalid URLs/paths as good as possible
|
||||||
public static String sanitize(String original) {
|
public static String sanitize(String original) {
|
||||||
if (original == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
String url = original;
|
String url = original;
|
||||||
|
|
||||||
// ":" is reserved as scheme/port separator, but we assume http:// and https:// URLs only
|
// ":" is reserved as scheme/port separator, but we assume http:// and https:// URLs only
|
||||||
|
@ -97,9 +97,14 @@ public class Contact extends Resource {
|
|||||||
super(localID, resourceName, eTag);
|
super(localID, resourceName, eTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initRemoteFields() {
|
public void generateUID() {
|
||||||
uid = UUID.randomUUID().toString();
|
uid = UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateName() {
|
||||||
name = uid + ".vcf";
|
name = uid + ".vcf";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,8 @@ import net.fortuna.ical4j.model.property.Summary;
|
|||||||
import net.fortuna.ical4j.model.property.Transp;
|
import net.fortuna.ical4j.model.property.Transp;
|
||||||
import net.fortuna.ical4j.model.property.Uid;
|
import net.fortuna.ical4j.model.property.Uid;
|
||||||
import net.fortuna.ical4j.model.property.Version;
|
import net.fortuna.ical4j.model.property.Version;
|
||||||
|
import net.fortuna.ical4j.util.SimpleHostInfo;
|
||||||
|
import net.fortuna.ical4j.util.UidGenerator;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
@ -102,9 +104,15 @@ public class Event extends Resource {
|
|||||||
super(localID, name, ETag);
|
super(localID, name, ETag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initRemoteFields() {
|
public void generateUID() {
|
||||||
uid = DavSyncAdapter.generateUID();
|
UidGenerator generator = new UidGenerator(new SimpleHostInfo(DavSyncAdapter.getAndroidID()), String.valueOf(android.os.Process.myPid()));
|
||||||
|
uid = generator.generateUid().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateName() {
|
||||||
name = uid.replace("@", "_") + ".ics";
|
name = uid.replace("@", "_") + ".ics";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +135,7 @@ public class Event extends Resource {
|
|||||||
uid = event.getUid().getValue();
|
uid = event.getUid().getValue();
|
||||||
else {
|
else {
|
||||||
Log.w(TAG, "Received VEVENT without UID, generating new one");
|
Log.w(TAG, "Received VEVENT without UID, generating new one");
|
||||||
uid = DavSyncAdapter.generateUID();
|
generateUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
dtStart = event.getStartDate(); validateTimeZone(dtStart);
|
dtStart = event.getStartDate(); validateTimeZone(dtStart);
|
||||||
|
@ -262,7 +262,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
break;
|
break;
|
||||||
case Phone.TYPE_CUSTOM:
|
case Phone.TYPE_CUSTOM:
|
||||||
String customType = cursor.getString(1);
|
String customType = cursor.getString(1);
|
||||||
if (customType != null && !customType.isEmpty())
|
if (!StringUtils.isEmpty(customType))
|
||||||
number.addType(TelephoneType.get(labelToXName(customType)));
|
number.addType(TelephoneType.get(labelToXName(customType)));
|
||||||
}
|
}
|
||||||
c.getPhoneNumbers().add(number);
|
c.getPhoneNumbers().add(number);
|
||||||
@ -287,7 +287,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
break;
|
break;
|
||||||
case Email.TYPE_CUSTOM:
|
case Email.TYPE_CUSTOM:
|
||||||
String customType = cursor.getString(2);
|
String customType = cursor.getString(2);
|
||||||
if (customType != null && !customType.isEmpty())
|
if (!StringUtils.isEmpty(customType))
|
||||||
email.addType(EmailType.get(labelToXName(customType)));
|
email.addType(EmailType.get(labelToXName(customType)));
|
||||||
}
|
}
|
||||||
c.getEmails().add(email);
|
c.getEmails().add(email);
|
||||||
@ -314,9 +314,9 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
String org = cursor.getString(0),
|
String org = cursor.getString(0),
|
||||||
role = cursor.getString(1);
|
role = cursor.getString(1);
|
||||||
if (org != null && !org.isEmpty())
|
if (!StringUtils.isEmpty(org))
|
||||||
c.setOrganization(org);
|
c.setOrganization(org);
|
||||||
if (role != null && !role.isEmpty())
|
if (!StringUtils.isEmpty(role))
|
||||||
c.setRole(role);
|
c.setRole(role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
break;
|
break;
|
||||||
case Im.TYPE_CUSTOM:
|
case Im.TYPE_CUSTOM:
|
||||||
String customType = cursor.getString(2);
|
String customType = cursor.getString(2);
|
||||||
if (customType != null && !customType.isEmpty())
|
if (!StringUtils.isEmpty(customType))
|
||||||
impp.addType(ImppType.get(labelToXName(customType)));
|
impp.addType(ImppType.get(labelToXName(customType)));
|
||||||
}
|
}
|
||||||
c.getImpps().add(impp);
|
c.getImpps().add(impp);
|
||||||
@ -416,7 +416,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
break;
|
break;
|
||||||
case StructuredPostal.TYPE_CUSTOM:
|
case StructuredPostal.TYPE_CUSTOM:
|
||||||
String customType = cursor.getString(2);
|
String customType = cursor.getString(2);
|
||||||
if (customType != null && !customType.isEmpty())
|
if (!StringUtils.isEmpty(customType))
|
||||||
address.addType(AddressType.get(labelToXName(customType)));
|
address.addType(AddressType.get(labelToXName(customType)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -469,15 +469,15 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
Impp impp = new Impp("sip:" + cursor.getString(0));
|
Impp impp = new Impp("sip:" + cursor.getString(0));
|
||||||
switch (cursor.getInt(1)) {
|
switch (cursor.getInt(1)) {
|
||||||
case Im.TYPE_HOME:
|
case SipAddress.TYPE_HOME:
|
||||||
impp.addType(ImppType.HOME);
|
impp.addType(ImppType.HOME);
|
||||||
break;
|
break;
|
||||||
case Im.TYPE_WORK:
|
case SipAddress.TYPE_WORK:
|
||||||
impp.addType(ImppType.WORK);
|
impp.addType(ImppType.WORK);
|
||||||
break;
|
break;
|
||||||
case Im.TYPE_CUSTOM:
|
case SipAddress.TYPE_CUSTOM:
|
||||||
String customType = cursor.getString(2);
|
String customType = cursor.getString(2);
|
||||||
if (customType != null && !customType.isEmpty())
|
if (!StringUtils.isEmpty(customType))
|
||||||
impp.addType(ImppType.get(labelToXName(customType)));
|
impp.addType(ImppType.get(labelToXName(customType)));
|
||||||
}
|
}
|
||||||
c.getImpps().add(impp);
|
c.getImpps().add(impp);
|
||||||
@ -544,7 +544,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
|
|
||||||
// TODO relations
|
// TODO relations
|
||||||
|
|
||||||
// SIP address built by buildIMPP
|
// SIP addresses built by buildIMPP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -766,7 +766,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
* country
|
* country
|
||||||
*/
|
*/
|
||||||
String formattedAddress = address.getLabel();
|
String formattedAddress = address.getLabel();
|
||||||
if (formattedAddress == null || formattedAddress.isEmpty()) {
|
if (StringUtils.isEmpty(formattedAddress)) {
|
||||||
String lineStreet = StringUtils.join(new String[] { address.getStreetAddress(), address.getPoBox(), address.getExtendedAddress() }, " "),
|
String lineStreet = StringUtils.join(new String[] { address.getStreetAddress(), address.getPoBox(), address.getExtendedAddress() }, " "),
|
||||||
lineLocality = StringUtils.join(new String[] { address.getPostalCode(), address.getLocality() }, " ");
|
lineLocality = StringUtils.join(new String[] { address.getPostalCode(), address.getLocality() }, " ");
|
||||||
|
|
||||||
@ -847,14 +847,15 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String xNameToLabel(String xname) {
|
protected String xNameToLabel(String xname) {
|
||||||
if (xname == null)
|
// "X-MY_PROPERTY"
|
||||||
return null;
|
|
||||||
// "x-my_property"
|
|
||||||
// 1. ensure lower case -> "x-my_property"
|
// 1. ensure lower case -> "x-my_property"
|
||||||
// 2. remove x- from beginning -> "my_property"
|
// 2. remove x- from beginning -> "my_property"
|
||||||
// 3. replace "_" by " " -> "my property"
|
// 3. replace "_" by " " -> "my property"
|
||||||
// 4. capitalize -> "My Property"
|
// 4. capitalize -> "My Property"
|
||||||
return WordUtils.capitalize(StringUtils.removeStart(xname.toLowerCase(Locale.US), "x-").replaceAll("_"," "));
|
String lowerCase = StringUtils.lowerCase(xname, Locale.US),
|
||||||
|
withoutPrefix = StringUtils.removeStart(lowerCase, "x-"),
|
||||||
|
withSpaces = StringUtils.replace(withoutPrefix, "_", " ");
|
||||||
|
return WordUtils.capitalize(withSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -235,29 +235,29 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
// recurrence
|
// recurrence
|
||||||
try {
|
try {
|
||||||
String duration = cursor.getString(18);
|
String duration = cursor.getString(18);
|
||||||
if (duration != null && !duration.isEmpty())
|
if (!StringUtils.isEmpty(duration))
|
||||||
e.setDuration(new Duration(new Dur(duration)));
|
e.setDuration(new Duration(new Dur(duration)));
|
||||||
|
|
||||||
String strRRule = cursor.getString(10);
|
String strRRule = cursor.getString(10);
|
||||||
if (strRRule != null && !strRRule.isEmpty())
|
if (!StringUtils.isEmpty(strRRule))
|
||||||
e.setRrule(new RRule(strRRule));
|
e.setRrule(new RRule(strRRule));
|
||||||
|
|
||||||
String strRDate = cursor.getString(11);
|
String strRDate = cursor.getString(11);
|
||||||
if (strRDate != null && !strRDate.isEmpty()) {
|
if (!StringUtils.isEmpty(strRDate)) {
|
||||||
RDate rDate = new RDate();
|
RDate rDate = new RDate();
|
||||||
rDate.setValue(strRDate);
|
rDate.setValue(strRDate);
|
||||||
e.setRdate(rDate);
|
e.setRdate(rDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
String strExRule = cursor.getString(12);
|
String strExRule = cursor.getString(12);
|
||||||
if (strExRule != null && !strExRule.isEmpty()) {
|
if (!StringUtils.isEmpty(strExRule)) {
|
||||||
ExRule exRule = new ExRule();
|
ExRule exRule = new ExRule();
|
||||||
exRule.setValue(strExRule);
|
exRule.setValue(strExRule);
|
||||||
e.setExrule(exRule);
|
e.setExrule(exRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
String strExDate = cursor.getString(13);
|
String strExDate = cursor.getString(13);
|
||||||
if (strExDate != null && !strExDate.isEmpty()) {
|
if (!StringUtils.isEmpty(strExDate)) {
|
||||||
// ignored, see https://code.google.com/p/android/issues/detail?id=21426
|
// ignored, see https://code.google.com/p/android/issues/detail?id=21426
|
||||||
ExDate exDate = new ExDate();
|
ExDate exDate = new ExDate();
|
||||||
exDate.setValue(strExDate);
|
exDate.setValue(strExDate);
|
||||||
|
@ -122,7 +122,8 @@ public abstract class LocalCollection<T extends Resource> {
|
|||||||
|
|
||||||
// new record: generate UID + remote file name so that we can upload
|
// new record: generate UID + remote file name so that we can upload
|
||||||
T resource = findById(id, false);
|
T resource = findById(id, false);
|
||||||
resource.initRemoteFields();
|
resource.generateUID();
|
||||||
|
resource.generateName();
|
||||||
// write generated UID + remote file name into database
|
// write generated UID + remote file name into database
|
||||||
ContentValues values = new ContentValues(2);
|
ContentValues values = new ContentValues(2);
|
||||||
values.put(entryColumnUID(), resource.getUid());
|
values.put(entryColumnUID(), resource.getUid());
|
||||||
|
@ -65,9 +65,8 @@ public abstract class RemoteCollection<T extends Resource> {
|
|||||||
if (collection.getMembers() != null) {
|
if (collection.getMembers() != null) {
|
||||||
for (WebDavResource member : collection.getMembers())
|
for (WebDavResource member : collection.getMembers())
|
||||||
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]);
|
||||||
} else
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -35,8 +35,9 @@ public abstract class Resource {
|
|||||||
this.localID = localID;
|
this.localID = localID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets resource name and UID
|
// sets UID and resource name (= remote file name)
|
||||||
public abstract void initRemoteFields();
|
public abstract void generateUID();
|
||||||
|
public abstract void generateName();
|
||||||
|
|
||||||
public abstract void parseEntity(InputStream entity) throws IOException, ParserException, VCardException;
|
public abstract void parseEntity(InputStream entity) throws IOException, ParserException, VCardException;
|
||||||
public abstract ByteArrayOutputStream toEntity() throws IOException, ValidationException;
|
public abstract ByteArrayOutputStream toEntity() throws IOException, ValidationException;
|
||||||
|
@ -3,8 +3,7 @@ package at.bitfire.davdroid.syncadapter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.fortuna.ical4j.util.SimpleHostInfo;
|
import lombok.Getter;
|
||||||
import net.fortuna.ical4j.util.UidGenerator;
|
|
||||||
|
|
||||||
import org.apache.http.HttpException;
|
import org.apache.http.HttpException;
|
||||||
import org.apache.http.auth.AuthenticationException;
|
import org.apache.http.auth.AuthenticationException;
|
||||||
@ -29,25 +28,20 @@ public abstract class DavSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
|
|
||||||
protected AccountManager accountManager;
|
protected AccountManager accountManager;
|
||||||
|
|
||||||
private static String androidID;
|
@Getter private static String androidID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DavSyncAdapter(Context context) {
|
public DavSyncAdapter(Context context) {
|
||||||
super(context, true);
|
super(context, true);
|
||||||
|
|
||||||
|
synchronized(this) {
|
||||||
|
if (androidID == null)
|
||||||
androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||||
|
}
|
||||||
|
|
||||||
accountManager = AccountManager.get(context);
|
accountManager = AccountManager.get(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String generateUID() {
|
|
||||||
UidGenerator generator = new UidGenerator(new SimpleHostInfo(androidID), String.valueOf(android.os.Process.myPid()));
|
|
||||||
return generator.generateUid().getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract Map<LocalCollection<?>, RemoteCollection<?>> getSyncPairs(Account account, ContentProviderClient provider);
|
protected abstract Map<LocalCollection<?>, RemoteCollection<?>> getSyncPairs(Account account, ContentProviderClient provider);
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,17 +59,15 @@ public class SyncManager {
|
|||||||
remotelyUpdated = new HashSet<Resource>();
|
remotelyUpdated = new HashSet<Resource>();
|
||||||
|
|
||||||
Resource[] remoteResources = remote.getMemberETags();
|
Resource[] remoteResources = remote.getMemberETags();
|
||||||
if (remoteResources != null) {
|
|
||||||
for (Resource remoteResource : remoteResources) {
|
for (Resource remoteResource : remoteResources) {
|
||||||
try {
|
try {
|
||||||
Resource localResource = local.findByRemoteName(remoteResource.getName(), false);
|
Resource localResource = local.findByRemoteName(remoteResource.getName(), false);
|
||||||
if (localResource.getETag() == null || !localResource.getETag().equals(remoteResource.getETag()))
|
if (!remoteResource.getETag().equals(localResource.getETag()))
|
||||||
remotelyUpdated.add(remoteResource);
|
remotelyUpdated.add(remoteResource);
|
||||||
} catch(RecordNotFoundException e) {
|
} catch(RecordNotFoundException e) {
|
||||||
remotelyAdded.add(remoteResource);
|
remotelyAdded.add(remoteResource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// PHASE 3: pull remote changes from server
|
// PHASE 3: pull remote changes from server
|
||||||
syncResult.stats.numInserts = pullNew(local, remote, remotelyAdded.toArray(new Resource[0]));
|
syncResult.stats.numInserts = pullNew(local, remote, remotelyAdded.toArray(new Resource[0]));
|
||||||
|
Loading…
Reference in New Issue
Block a user