Skip to content

Commit a6fa824

Browse files
committed
Issue #171 - Fixing Lint Warnings in Category Package
Fixing Some Android Lint and SonarLint Warnings in this package: * `fr.free.nrw.commons.category` Some of the fixes were: * Switching the try/catch/finally blocks for database querying in `CategoryDao` into try-with-resources blocks, with the Cursor object getting set as the closable resource * Switching one field type in the sqlite "Create Table Statement" in CategoryDao from STRING to TEXT * Throwing the new DAOException instead of a generic RuntimeException in CategoryDao * Logging some Exceptions using Timber instead of `e.printStackTrace()` * A few access modifier changes to be more restrictive * Adding a private constructor to some static classes * Made some constant String variables for recurring Strings * Changed the switch cases with only one case into if/else statements * Added some @nonnull and @nullable annotations to methods that inherit methods that use those annotations
1 parent 54e4a3f commit a6fa824

11 files changed

+118
-117
lines changed

app/src/main/java/fr/free/nrw/commons/category/CategoriesAdapterFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.Collections;
77
import java.util.List;
88

9-
public class CategoriesAdapterFactory {
9+
class CategoriesAdapterFactory {
1010
private final CategoryClickedListener listener;
1111

1212
public CategoriesAdapterFactory(CategoryClickedListener listener) {
@@ -17,7 +17,7 @@ public CategoryRendererAdapter create(List<CategoryItem> placeList) {
1717
RendererBuilder<CategoryItem> builder = new RendererBuilder<CategoryItem>()
1818
.bind(CategoryItem.class, new CategoriesRenderer(listener));
1919
ListAdapteeCollection<CategoryItem> collection = new ListAdapteeCollection<>(
20-
placeList != null ? placeList : Collections.<CategoryItem>emptyList());
20+
placeList != null ? placeList : Collections.emptyList());
2121
return new CategoryRendererAdapter(builder, collection);
2222
}
2323
}

app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.Date;
99
import java.util.HashMap;
1010
import java.util.List;
11-
11+
import java.util.Map;
1212
import javax.inject.Inject;
1313
import javax.inject.Named;
1414

@@ -21,15 +21,15 @@
2121
/**
2222
* The model class for categories in upload
2323
*/
24-
public class CategoriesModel{
24+
public class CategoriesModel {
2525
private static final int SEARCH_CATS_LIMIT = 25;
2626

2727
private final CategoryClient categoryClient;
2828
private final CategoryDao categoryDao;
2929
private final JsonKvStore directKvStore;
3030

31-
private HashMap<String, ArrayList<String>> categoriesCache;
32-
private List<CategoryItem> selectedCategories;
31+
private final Map<String, ArrayList<String>> categoriesCache;
32+
private final List<CategoryItem> selectedCategories;
3333

3434
@Inject GpsCategoryModel gpsCategoryModel;
3535
@Inject
@@ -82,7 +82,7 @@ public boolean containsYear(String item) {
8282
* Updates category count in category dao
8383
* @param item
8484
*/
85-
public void updateCategoryCount(CategoryItem item) {
85+
private void updateCategoryCount(CategoryItem item) {
8686
Category category = categoryDao.find(item.getName());
8787

8888
// Newly used category...
@@ -94,7 +94,7 @@ public void updateCategoryCount(CategoryItem item) {
9494
categoryDao.save(category);
9595
}
9696

97-
boolean cacheContainsKey(String term) {
97+
private boolean cacheContainsKey(String term) {
9898
return categoriesCache.containsKey(term);
9999
}
100100
//endregion
@@ -111,7 +111,7 @@ public Observable<CategoryItem> searchAll(String term, List<String> imageTitleLi
111111
Observable<CategoryItem> categoryItemObservable = gpsCategories()
112112
.concatWith(titleCategories(imageTitleList));
113113
if (hasDirectCategories()) {
114-
categoryItemObservable.concatWith(directCategories().concatWith(recentCategories()));
114+
categoryItemObservable = categoryItemObservable.concatWith(directCategories().concatWith(recentCategories()));
115115
}
116116
return categoryItemObservable;
117117
}
@@ -153,11 +153,11 @@ private boolean hasDirectCategories() {
153153
private Observable<CategoryItem> directCategories() {
154154
String directCategory = directKvStore.getString("Category", "");
155155
List<String> categoryList = new ArrayList<>();
156-
Timber.d("Direct category found: " + directCategory);
156+
Timber.d("Direct category found: %s", directCategory);
157157

158158
if (!directCategory.equals("")) {
159159
categoryList.add(directCategory);
160-
Timber.d("DirectCat does not equal emptyString. Direct Cat list has " + categoryList);
160+
Timber.d("DirectCat does not equal emptyString. Direct Cat list has %s", categoryList);
161161
}
162162
return Observable.fromIterable(categoryList).map(name -> new CategoryItem(name, false));
163163
}
@@ -166,7 +166,7 @@ private Observable<CategoryItem> directCategories() {
166166
* Returns GPS categories
167167
* @return
168168
*/
169-
Observable<CategoryItem> gpsCategories() {
169+
private Observable<CategoryItem> gpsCategories() {
170170
return Observable.fromIterable(gpsCategoryModel.getCategoryList())
171171
.map(name -> new CategoryItem(name, false));
172172
}
@@ -217,15 +217,15 @@ public void onCategoryItemClicked(CategoryItem item) {
217217
* Select's category
218218
* @param item
219219
*/
220-
public void selectCategory(CategoryItem item) {
220+
private void selectCategory(CategoryItem item) {
221221
selectedCategories.add(item);
222222
}
223223

224224
/**
225225
* Unselect Category
226226
* @param item
227227
*/
228-
public void unselectCategory(CategoryItem item) {
228+
private void unselectCategory(CategoryItem item) {
229229
selectedCategories.remove(item);
230230
}
231231

app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public class CategoryContentProvider extends CommonsDaggerContentProvider {
3232

3333
private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH);
3434

35+
private static final String UNKNOWN_URL = "Unknown URI: ";
36+
3537
static {
3638
uriMatcher.addURI(BuildConfig.CATEGORY_AUTHORITY, BASE_PATH, CATEGORIES);
3739
uriMatcher.addURI(BuildConfig.CATEGORY_AUTHORITY, BASE_PATH + "/#", CATEGORIES_ID);
@@ -71,7 +73,7 @@ public Cursor query(@NonNull Uri uri, String[] projection, String selection,
7173
);
7274
break;
7375
default:
74-
throw new IllegalArgumentException("Unknown URI" + uri);
76+
throw new IllegalArgumentException(UNKNOWN_URL + uri);
7577
}
7678

7779
cursor.setNotificationUri(getContext().getContentResolver(), uri);
@@ -90,12 +92,10 @@ public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
9092
int uriType = uriMatcher.match(uri);
9193
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
9294
long id;
93-
switch (uriType) {
94-
case CATEGORIES:
95-
id = sqlDB.insert(TABLE_NAME, null, contentValues);
96-
break;
97-
default:
98-
throw new IllegalArgumentException("Unknown URI: " + uri);
95+
if (uriType == CATEGORIES) {
96+
id = sqlDB.insert(TABLE_NAME, null, contentValues);
97+
} else {
98+
throw new IllegalArgumentException(UNKNOWN_URL + uri);
9999
}
100100
getContext().getContentResolver().notifyChange(uri, null);
101101
return Uri.parse(BASE_URI + "/" + id);
@@ -113,15 +113,13 @@ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) {
113113
int uriType = uriMatcher.match(uri);
114114
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
115115
sqlDB.beginTransaction();
116-
switch (uriType) {
117-
case CATEGORIES:
118-
for (ContentValues value : values) {
119-
Timber.d("Inserting! %s", value);
120-
sqlDB.insert(TABLE_NAME, null, value);
121-
}
122-
break;
123-
default:
124-
throw new IllegalArgumentException("Unknown URI: " + uri);
116+
if (uriType == CATEGORIES) {
117+
for (ContentValues value : values) {
118+
Timber.d("Inserting! %s", value);
119+
sqlDB.insert(TABLE_NAME, null, value);
120+
}
121+
} else {
122+
throw new IllegalArgumentException(UNKNOWN_URL + uri);
125123
}
126124
sqlDB.setTransactionSuccessful();
127125
sqlDB.endTransaction();
@@ -145,21 +143,19 @@ outside world (exported="false"). Even then, we should make sure to sanitize
145143
int uriType = uriMatcher.match(uri);
146144
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
147145
int rowsUpdated;
148-
switch (uriType) {
149-
case CATEGORIES_ID:
150-
if (TextUtils.isEmpty(selection)) {
151-
int id = Integer.valueOf(uri.getLastPathSegment());
152-
rowsUpdated = sqlDB.update(TABLE_NAME,
153-
contentValues,
154-
COLUMN_ID + " = ?",
155-
new String[]{String.valueOf(id)});
156-
} else {
157-
throw new IllegalArgumentException(
158-
"Parameter `selection` should be empty when updating an ID");
159-
}
160-
break;
161-
default:
162-
throw new IllegalArgumentException("Unknown URI: " + uri + " with type " + uriType);
146+
if (uriType == CATEGORIES_ID) {
147+
if (TextUtils.isEmpty(selection)) {
148+
int id = Integer.valueOf(uri.getLastPathSegment());
149+
rowsUpdated = sqlDB.update(TABLE_NAME,
150+
contentValues,
151+
COLUMN_ID + " = ?",
152+
new String[]{String.valueOf(id)});
153+
} else {
154+
throw new IllegalArgumentException(
155+
"Parameter `selection` should be empty when updating an ID");
156+
}
157+
} else {
158+
throw new IllegalArgumentException(UNKNOWN_URL + uri + " with type " + uriType);
163159
}
164160
getContext().getContentResolver().notifyChange(uri, null);
165161
return rowsUpdated;

app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import androidx.annotation.NonNull;
99
import androidx.annotation.Nullable;
1010

11+
import fr.free.nrw.commons.data.DAOException;
1112
import java.util.ArrayList;
1213
import java.util.Date;
1314
import java.util.List;
@@ -34,7 +35,7 @@ public void save(Category category) {
3435
db.update(category.getContentUri(), toContentValues(category), null, null);
3536
}
3637
} catch (RemoteException e) {
37-
throw new RuntimeException(e);
38+
throw new DAOException(e);
3839
} finally {
3940
db.release();
4041
}
@@ -48,25 +49,21 @@ public void save(Category category) {
4849
*/
4950
@Nullable
5051
Category find(String name) {
51-
Cursor cursor = null;
5252
ContentProviderClient db = clientProvider.get();
53-
try {
54-
cursor = db.query(
53+
try (Cursor cursor = db.query(
5554
CategoryContentProvider.BASE_URI,
5655
Table.ALL_FIELDS,
5756
Table.COLUMN_NAME + "=?",
5857
new String[]{name},
59-
null);
58+
null)) {
59+
6060
if (cursor != null && cursor.moveToFirst()) {
6161
return fromCursor(cursor);
6262
}
6363
} catch (RemoteException e) {
6464
// This feels lazy, but to hell with checked exceptions. :)
65-
throw new RuntimeException(e);
65+
throw new DAOException(e);
6666
} finally {
67-
if (cursor != null) {
68-
cursor.close();
69-
}
7067
db.release();
7168
}
7269
return null;
@@ -80,26 +77,22 @@ Category find(String name) {
8077
@NonNull
8178
List<String> recentCategories(int limit) {
8279
List<String> items = new ArrayList<>();
83-
Cursor cursor = null;
8480
ContentProviderClient db = clientProvider.get();
85-
try {
86-
cursor = db.query(
81+
try (Cursor cursor = db.query(
8782
CategoryContentProvider.BASE_URI,
8883
Table.ALL_FIELDS,
8984
null,
9085
new String[]{},
91-
Table.COLUMN_LAST_USED + " DESC");
86+
Table.COLUMN_LAST_USED + " DESC")){
87+
9288
// fixme add a limit on the original query instead of falling out of the loop?
9389
while (cursor != null && cursor.moveToNext()
9490
&& cursor.getPosition() < limit) {
9591
items.add(fromCursor(cursor).getName());
9692
}
9793
} catch (RemoteException e) {
98-
throw new RuntimeException(e);
94+
throw new DAOException(e);
9995
} finally {
100-
if (cursor != null) {
101-
cursor.close();
102-
}
10396
db.release();
10497
}
10598
return items;
@@ -133,7 +126,7 @@ public static class Table {
133126
static final String COLUMN_TIMES_USED = "times_used";
134127

135128
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
136-
public static final String[] ALL_FIELDS = {
129+
protected static final String[] ALL_FIELDS = {
137130
COLUMN_ID,
138131
COLUMN_NAME,
139132
COLUMN_LAST_USED,
@@ -144,11 +137,14 @@ public static class Table {
144137

145138
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
146139
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
147-
+ COLUMN_NAME + " STRING,"
140+
+ COLUMN_NAME + " TEXT,"
148141
+ COLUMN_LAST_USED + " INTEGER,"
149142
+ COLUMN_TIMES_USED + " INTEGER"
150143
+ ");";
151144

145+
private Table() {
146+
}
147+
152148
public static void onCreate(SQLiteDatabase db) {
153149
db.execSQL(CREATE_TABLE_STATEMENT);
154150
}
@@ -178,7 +174,6 @@ public static void onUpdate(SQLiteDatabase db, int from, int to) {
178174
if (from == 5) {
179175
from++;
180176
onUpdate(db, from, to);
181-
return;
182177
}
183178
}
184179
}

0 commit comments

Comments
 (0)