diff --git a/.idea/codeInsightSettings.xml b/.idea/codeInsightSettings.xml new file mode 100644 index 000000000..b380aeb58 --- /dev/null +++ b/.idea/codeInsightSettings.xml @@ -0,0 +1,9 @@ + + + + + javax.annotation.Nonnull + javax.annotation.Nullable + + + \ No newline at end of file diff --git a/opentasks/src/main/java/org/dmfs/tasks/model/ContentSet.java b/opentasks/src/main/java/org/dmfs/tasks/model/ContentSet.java index 1e32f0f21..6b803925e 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/model/ContentSet.java +++ b/opentasks/src/main/java/org/dmfs/tasks/model/ContentSet.java @@ -22,6 +22,8 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.util.Log; import org.dmfs.tasks.utils.AsyncContentLoader; @@ -81,16 +83,6 @@ public final class ContentSet implements OnContentLoadedListener, Parcelable */ private final Set mPendingNotifications = new HashSet(); - /** - * Holds the name of the keys we've updated in {@link #mAfterContentValues}. - *

- * Before Android SDK level 11 there is no {@link ContentValues#keySet()} method. To be able to determine the keys in there we have to maintain the set - * ourselves. - *

- * Don't use this before calling {@link #ensureAfter()} at least once. - */ - private Set mAfterKeys; - /** * Indicates that loading is in process. */ @@ -112,13 +104,8 @@ private ContentSet() * @param uri * A content URI, either a directory URI or an item URI. */ - public ContentSet(Uri uri) + public ContentSet(@NonNull Uri uri) { - if (uri == null) - { - throw new IllegalArgumentException("uri must not be null"); - } - mUri = uri; } @@ -129,13 +116,8 @@ public ContentSet(Uri uri) * @param other * The {@link ContentSet} to clone. */ - public ContentSet(ContentSet other) + public ContentSet(@NonNull ContentSet other) { - if (other == null) - { - throw new IllegalArgumentException("other must not be null"); - } - if (other.mBeforeContentValues != null) { mBeforeContentValues = new ContentValues(other.mBeforeContentValues); @@ -144,7 +126,6 @@ public ContentSet(ContentSet other) if (other.mAfterContentValues != null) { mAfterContentValues = new ContentValues(other.mAfterContentValues); - mAfterKeys = new HashSet(other.mAfterKeys); } mUri = other.mUri; @@ -159,7 +140,7 @@ public ContentSet(ContentSet other) * @param mapper * The {@link ContentValueMapper} to use when loading the values. */ - public void update(Context context, ContentValueMapper mapper) + public void update(@NonNull Context context, @NonNull ContentValueMapper mapper) { String itemType = context.getContentResolver().getType(mUri); if (itemType != null && !itemType.startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE)) @@ -175,7 +156,7 @@ public void update(Context context, ContentValueMapper mapper) @Override - public void onContentLoaded(ContentValues values) + public void onContentLoaded(@NonNull ContentValues values) { mBeforeContentValues = values; mLoading = false; @@ -200,7 +181,7 @@ public boolean isLoading() * @param context * A context. */ - public void delete(Context context) + public void delete(@NonNull Context context) { if (mUri != null) { @@ -210,7 +191,6 @@ public void delete(Context context) context.getContentResolver().delete(mUri, null, null); mBeforeContentValues = null; mAfterContentValues = null; - mAfterKeys = null; mUri = null; } else @@ -226,10 +206,16 @@ public void delete(Context context) } - public Uri persist(Context context) + @NonNull + public Uri persist(@NonNull Context context) { if (mAfterContentValues == null || mAfterContentValues.size() == 0) { + if (mUri == null) + { + throw new IllegalStateException("Task uri is null, cannot persist(). (Called after delete()?)"); + } + // nothing to do here return mUri; } @@ -247,6 +233,11 @@ else if (isUpdate()) mAfterContentValues = null; + if (mUri == null) + { + throw new IllegalStateException("Task uri is null, cannot persist(). (Called after delete()?)"); + } + return mUri; } @@ -263,26 +254,26 @@ public boolean isUpdate() } - public boolean containsKey(String key) + public boolean containsKey(@NonNull String key) { return mAfterContentValues != null && mAfterContentValues.containsKey(key) || mBeforeContentValues != null && mBeforeContentValues.containsKey(key); } - public boolean persistsKey(String key) + private boolean persistsKey(@NonNull String key) { return mAfterContentValues != null && mAfterContentValues.containsKey(key); } - public boolean updatesAnyKey(Set keys) + public boolean updatesAnyKey(@NonNull Set keys) { if (mAfterContentValues == null) { return false; } - Set keySet = new HashSet(mAfterKeys); + Set keySet = new HashSet<>(mAfterContentValues.keySet()); keySet.retainAll(keys); @@ -291,9 +282,9 @@ public boolean updatesAnyKey(Set keys) } - public void ensureUpdates(Set keys) + public void ensureUpdates(@NonNull Set keys) { - if (mBeforeContentValues == null || keys == null || keys.isEmpty()) + if (mBeforeContentValues == null || keys.isEmpty()) { // nothing to do return; @@ -328,6 +319,7 @@ public void ensureUpdates(Set keys) } + @NonNull private ContentValues ensureAfter() { ContentValues values = mAfterContentValues; @@ -335,14 +327,12 @@ private ContentValues ensureAfter() { values = new ContentValues(); mAfterContentValues = values; - // also create mAfterKeys - mAfterKeys = new HashSet(); } return values; } - public void put(String key, Integer value) + public void put(@NonNull String key, @Nullable Integer value) { Integer oldValue = getAsInteger(key); if (value != null && !value.equals(oldValue) || value == null && oldValue != null) @@ -354,20 +344,19 @@ public void put(String key, Integer value) { // value equals before value, so remove it from after values mAfterContentValues.remove(key); - mAfterKeys.remove(key); notifyUpdateListeners(key); return; } } // value has changed, update ensureAfter().put(key, value); - mAfterKeys.add(key); notifyUpdateListeners(key); } } - public Integer getAsInteger(String key) + @Nullable + public Integer getAsInteger(@NonNull String key) { final ContentValues after = mAfterContentValues; if (after != null && after.containsKey(key)) @@ -378,7 +367,7 @@ public Integer getAsInteger(String key) } - public void put(String key, Long value) + public void put(@NonNull String key, @Nullable Long value) { Long oldValue = getAsLong(key); if (value != null && !value.equals(oldValue) || value == null && oldValue != null) @@ -390,19 +379,18 @@ public void put(String key, Long value) { // value equals before value, so remove it from after values mAfterContentValues.remove(key); - mAfterKeys.remove(key); notifyUpdateListeners(key); return; } } ensureAfter().put(key, value); - mAfterKeys.add(key); notifyUpdateListeners(key); } } - public Long getAsLong(String key) + @Nullable + public Long getAsLong(@NonNull String key) { final ContentValues after = mAfterContentValues; if (after != null && after.containsKey(key)) @@ -413,7 +401,7 @@ public Long getAsLong(String key) } - public void put(String key, String value) + public void put(@NonNull String key, @Nullable String value) { String oldValue = getAsString(key); if (value != null && !value.equals(oldValue) || value == null && oldValue != null) @@ -425,19 +413,18 @@ public void put(String key, String value) { // value equals before value, so remove it from after values mAfterContentValues.remove(key); - mAfterKeys.remove(key); notifyUpdateListeners(key); return; } } ensureAfter().put(key, value); - mAfterKeys.add(key); notifyUpdateListeners(key); } } - public String getAsString(String key) + @Nullable + public String getAsString(@NonNull String key) { final ContentValues after = mAfterContentValues; if (after != null && after.containsKey(key)) @@ -448,7 +435,7 @@ public String getAsString(String key) } - public void put(String key, Float value) + public void put(@NonNull String key, @Nullable Float value) { Float oldValue = getAsFloat(key); if (value != null && !value.equals(oldValue) || value == null && oldValue != null) @@ -460,19 +447,18 @@ public void put(String key, Float value) { // value equals before value, so remove it from after values mAfterContentValues.remove(key); - mAfterKeys.remove(key); notifyUpdateListeners(key); return; } } ensureAfter().put(key, value); - mAfterKeys.add(key); notifyUpdateListeners(key); } } - public Float getAsFloat(String key) + @Nullable + public Float getAsFloat(@Nullable String key) { final ContentValues after = mAfterContentValues; if (after != null && after.containsKey(key)) @@ -489,6 +475,7 @@ public Float getAsFloat(String key) * * @return The {@link Uri}. */ + @Nullable public Uri getUri() { return mUri; @@ -529,22 +516,24 @@ public void finishBulkUpdate() * @param key * The key of the value to remove. */ - public void remove(String key) + public void remove(@NonNull String key) { if (mAfterContentValues != null) { mAfterContentValues.putNull(key); - mAfterKeys.add(key); } else if (mBeforeContentValues != null && mBeforeContentValues.get(key) != null) { ensureAfter().putNull(key); - mAfterKeys.add(key); } } - public void addOnChangeListener(OnContentChangeListener listener, String key, boolean notify) + /** + * @param key + * the specific key in a {@link ContentSet} to listen the changes for, or null to be notified of full reloads. + */ + public void addOnChangeListener(@NonNull OnContentChangeListener listener, @Nullable String key, boolean notify) { Set listenerSet = mOnChangeListeners.get(key); if (listenerSet == null) @@ -563,7 +552,12 @@ public void addOnChangeListener(OnContentChangeListener listener, String key, bo } - public void removeOnChangeListener(OnContentChangeListener listener, String key) + /** + * @param key + * The specific key in a {@link ContentSet} to remove the listening about, or null to remove listening from full reloads. See {@link + * #addOnChangeListener(OnContentChangeListener, String, boolean)} as well. + */ + public void removeOnChangeListener(@NonNull OnContentChangeListener listener, @Nullable String key) { Set listenerSet = mOnChangeListeners.get(key); if (listenerSet != null) @@ -573,7 +567,7 @@ public void removeOnChangeListener(OnContentChangeListener listener, String key) } - private void notifyUpdateListeners(String key) + private void notifyUpdateListeners(@NonNull String key) { Set listenerSet = mOnChangeListeners.get(key); if (listenerSet != null) @@ -619,36 +613,15 @@ public void writeToParcel(Parcel dest, int flags) dest.writeParcelable(mUri, flags); dest.writeParcelable(mBeforeContentValues, flags); dest.writeParcelable(mAfterContentValues, flags); - - if (mAfterContentValues != null) - { - // It's not possible to write a Set to a parcel, so write the number of members and each member individually. - dest.writeInt(mAfterKeys.size()); - for (String key : mAfterKeys) - { - dest.writeString(key); - } - } } - public void readFromParcel(Parcel source) + private void readFromParcel(Parcel source) { ClassLoader loader = getClass().getClassLoader(); mUri = source.readParcelable(loader); mBeforeContentValues = source.readParcelable(loader); mAfterContentValues = source.readParcelable(loader); - - if (mAfterContentValues != null) - { - int count = source.readInt(); - Set keys = new HashSet(); - while (--count >= 0) - { - keys.add(source.readString()); - } - mAfterKeys = keys; - } } diff --git a/opentasks/src/main/java/org/dmfs/tasks/utils/OnContentLoadedListener.java b/opentasks/src/main/java/org/dmfs/tasks/utils/OnContentLoadedListener.java index 612be08fb..ce8f3544c 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/utils/OnContentLoadedListener.java +++ b/opentasks/src/main/java/org/dmfs/tasks/utils/OnContentLoadedListener.java @@ -17,6 +17,7 @@ package org.dmfs.tasks.utils; import android.content.ContentValues; +import android.support.annotation.NonNull; /** @@ -32,5 +33,5 @@ public interface OnContentLoadedListener * @param values * The loaded {@link ContentValues}. */ - public void onContentLoaded(ContentValues values); + void onContentLoaded(@NonNull ContentValues values); }