Minor improvements

* use weak references for DavService RefreshingStatusListener
* additional null checks for cases which shouldn't appear, but apparently appear
* additional database conflict handling for cases which shouldn't appear, but apparently appear
* setup by URL: null check for empty host names
* vcard4android: upgrade to ezvcard 0.9.10
pull/2/head
Ricki Hirner 8 years ago
parent 144643d6af
commit 9886507b7d

@ -55,13 +55,7 @@ android {
} }
} }
configurations.all {
exclude module: 'commons-logging' // undocumented part of Android
}
dependencies { dependencies {
provided 'org.projectlombok:lombok:1.16.8'
compile project(':dav4android') compile project(':dav4android')
compile project(':ical4android') compile project(':ical4android')
compile project(':vcard4android') compile project(':vcard4android')
@ -77,6 +71,7 @@ dependencies {
compile 'dnsjava:dnsjava:2.1.7' compile 'dnsjava:dnsjava:2.1.7'
compile 'org.apache.commons:commons-lang3:3.4' compile 'org.apache.commons:commons-lang3:3.4'
compile 'org.apache.commons:commons-collections4:4.1' compile 'org.apache.commons:commons-collections4:4.1'
provided 'org.projectlombok:lombok:1.16.8'
// for tests // for tests
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'

@ -31,6 +31,7 @@ import org.apache.commons.collections4.iterators.IteratorChain;
import org.apache.commons.collections4.iterators.SingletonIterator; import org.apache.commons.collections4.iterators.SingletonIterator;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -70,7 +71,7 @@ public class DavService extends Service {
private final IBinder binder = new InfoBinder(); private final IBinder binder = new InfoBinder();
private final Set<Long> runningRefresh = new HashSet<>(); private final Set<Long> runningRefresh = new HashSet<>();
private final List<RefreshingStatusListener> refreshingStatusListeners = new LinkedList<>(); private final List<WeakReference<RefreshingStatusListener>> refreshingStatusListeners = new LinkedList<>();
@Override @Override
@ -86,8 +87,11 @@ public class DavService extends Service {
case ACTION_REFRESH_COLLECTIONS: case ACTION_REFRESH_COLLECTIONS:
if (runningRefresh.add(id)) { if (runningRefresh.add(id)) {
new Thread(new RefreshCollections(id)).start(); new Thread(new RefreshCollections(id)).start();
for (RefreshingStatusListener listener : refreshingStatusListeners) for (WeakReference<RefreshingStatusListener> ref : refreshingStatusListeners) {
listener.onDavRefreshStatusChanged(id, true); RefreshingStatusListener listener = ref.get();
if (listener != null)
listener.onDavRefreshStatusChanged(id, true);
}
} }
break; break;
} }
@ -115,15 +119,19 @@ public class DavService extends Service {
return runningRefresh.contains(id); return runningRefresh.contains(id);
} }
public void addRefreshingStatusListener(RefreshingStatusListener listener, boolean callImmediate) { public void addRefreshingStatusListener(@NonNull RefreshingStatusListener listener, boolean callImmediate) {
refreshingStatusListeners.add(listener); refreshingStatusListeners.add(new WeakReference<>(listener));
if (callImmediate) if (callImmediate)
for (long id : runningRefresh) for (long id : runningRefresh)
listener.onDavRefreshStatusChanged(id, true); listener.onDavRefreshStatusChanged(id, true);
} }
public void removeRefreshingStatusListener(RefreshingStatusListener listener) { public void removeRefreshingStatusListener(@NonNull RefreshingStatusListener listener) {
refreshingStatusListeners.remove(listener); for (Iterator<WeakReference<RefreshingStatusListener>> iterator = refreshingStatusListeners.iterator(); iterator.hasNext(); ) {
RefreshingStatusListener item = iterator.next().get();
if (listener.equals(item))
iterator.remove();
}
} }
} }
@ -314,8 +322,11 @@ public class DavService extends Service {
dbHelper.close(); dbHelper.close();
runningRefresh.remove(service); runningRefresh.remove(service);
for (RefreshingStatusListener listener : refreshingStatusListeners) for (WeakReference<RefreshingStatusListener> ref : refreshingStatusListeners) {
listener.onDavRefreshStatusChanged(service, false); RefreshingStatusListener listener = ref.get();
if (listener != null)
listener.onDavRefreshStatusChanged(service, false);
}
} }
} }

@ -149,12 +149,15 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
Intent intent;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.refresh_address_books: case R.id.refresh_address_books:
Intent intent = new Intent(this, DavService.class); if (accountInfo.carddav != null) {
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS); intent = new Intent(this, DavService.class);
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.carddav.id); intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
startService(intent); intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.carddav.id);
startService(intent);
}
break; break;
case R.id.create_address_book: case R.id.create_address_book:
intent = new Intent(this, CreateAddressBookActivity.class); intent = new Intent(this, CreateAddressBookActivity.class);
@ -162,10 +165,12 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
startActivity(intent); startActivity(intent);
break; break;
case R.id.refresh_calendars: case R.id.refresh_calendars:
intent = new Intent(this, DavService.class); if (accountInfo.caldav != null) {
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS); intent = new Intent(this, DavService.class);
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.caldav.id); intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
startService(intent); intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.caldav.id);
startService(intent);
}
break; break;
case R.id.create_calendar: case R.id.create_calendar:
intent = new Intent(this, CreateCalendarActivity.class); intent = new Intent(this, CreateCalendarActivity.class);

@ -163,21 +163,21 @@ public class AccountDetailsFragment extends Fragment {
values.put(Services.SERVICE, service); values.put(Services.SERVICE, service);
if (info.principal != null) if (info.principal != null)
values.put(Services.PRINCIPAL, info.principal.toString()); values.put(Services.PRINCIPAL, info.principal.toString());
long serviceID = db.insertOrThrow(Services._TABLE, null, values); long serviceID = db.insertWithOnConflict(Services._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
// insert home sets // insert home sets
for (URI homeSet : info.homeSets) { for (URI homeSet : info.homeSets) {
values.clear(); values.clear();
values.put(HomeSets.SERVICE_ID, serviceID); values.put(HomeSets.SERVICE_ID, serviceID);
values.put(HomeSets.URL, homeSet.toString()); values.put(HomeSets.URL, homeSet.toString());
db.insertOrThrow(HomeSets._TABLE, null, values); db.insertWithOnConflict(HomeSets._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
} }
// insert collections // insert collections
for (CollectionInfo collection : info.collections.values()) { for (CollectionInfo collection : info.collections.values()) {
values = collection.toDB(); values = collection.toDB();
values.put(Collections.SERVICE_ID, serviceID); values.put(Collections.SERVICE_ID, serviceID);
db.insertOrThrow(Collections._TABLE, null, values); db.insertWithOnConflict(Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
} }
return serviceID; return serviceID;

@ -21,6 +21,8 @@ import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RadioButton; import android.widget.RadioButton;
import org.apache.commons.lang3.StringUtils;
import java.net.IDN; import java.net.IDN;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -121,14 +123,15 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
String scheme = baseUrl.getScheme(); String scheme = baseUrl.getScheme();
if ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme)) { if ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme)) {
String host = baseUrl.getHost(); String host = baseUrl.getHost();
if (host.isEmpty()) { if (StringUtils.isEmpty(host)) {
editBaseURL.setError(getString(R.string.login_url_host_name_required)); editBaseURL.setError(getString(R.string.login_url_host_name_required));
valid = false; valid = false;
} else try { } else
host = IDN.toASCII(host); try {
} catch(IllegalArgumentException e) { host = IDN.toASCII(host);
Constants.log.log(Level.WARNING, "Host name not conforming to RFC 3490", e); } catch(IllegalArgumentException e) {
} Constants.log.log(Level.WARNING, "Host name not conforming to RFC 3490", e);
}
String path = baseUrl.getEncodedPath(); String path = baseUrl.getEncodedPath();
int port = baseUrl.getPort(); int port = baseUrl.getPort();

@ -1 +1 @@
Subproject commit 3c86db909052c9d01d1979a9a5c32ef0fefd69dd Subproject commit 7577fcaa02d83ea5fbeeefa35511b45f3285ce95

@ -1 +1 @@
Subproject commit 046cdbf76911b2979c19e9219b069386d4b4cba7 Subproject commit fda39538a3407f2a6f6a208f06a4ef1dbc1bed40
Loading…
Cancel
Save