From fddb5927341f1e8b104dd1ff55cc97a628ef03b3 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Tue, 12 Nov 2019 21:53:54 +0100 Subject: [PATCH 01/12] Use relative paths --- .../odk/collect/android/FormNavigationTestCase.java | 10 +++------- .../collect/android/tasks/AuditEventSaveTaskTest.java | 5 ++--- .../java/org/odk/collect/android/test/TestUtils.java | 3 +-- .../org/odk/collect/android/application/Collect.java | 4 ++-- .../org/odk/collect/android/utilities/FileUtils.java | 8 +++----- .../org/odk/collect/android/widgets/VideoWidget.java | 4 +--- 6 files changed, 12 insertions(+), 22 deletions(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/FormNavigationTestCase.java b/collect_app/src/androidTest/java/org/odk/collect/android/FormNavigationTestCase.java index 5b6643ee1fe..47211c79989 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/FormNavigationTestCase.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/FormNavigationTestCase.java @@ -16,18 +16,18 @@ package org.odk.collect.android; -import android.os.Environment; - import org.javarosa.core.model.FormDef; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import org.odk.collect.android.application.Collect; import org.odk.collect.android.listeners.FormLoaderListener; import org.odk.collect.android.logic.FormController; import org.odk.collect.android.tasks.FormLoaderTask; import org.odk.collect.android.test.FormLoadingUtils; +import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.concurrent.ExecutionException; @@ -47,8 +47,6 @@ @RunWith(Parameterized.class) public class FormNavigationTestCase { - private static final String FORMS_DIRECTORY = "/odk/forms/"; - @Parameters(name = "{0}") public static Iterable data() { // Expected indices when swiping forward until the end of the form and back once. @@ -142,8 +140,6 @@ private void copyToSdCard(String formName) throws IOException { } private static String formPath(String formName) { - return Environment.getExternalStorageDirectory().getPath() - + FORMS_DIRECTORY - + formName; + return Collect.FORMS_PATH + File.separator + formName; } } \ No newline at end of file diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/AuditEventSaveTaskTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/AuditEventSaveTaskTest.java index b2699381790..0b9325e1952 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/AuditEventSaveTaskTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/AuditEventSaveTaskTest.java @@ -16,8 +16,6 @@ package org.odk.collect.android.tasks; -import android.os.Environment; - import androidx.test.rule.GrantPermissionRule; import androidx.test.runner.AndroidJUnit4; @@ -28,6 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.odk.collect.android.application.Collect; import org.odk.collect.android.logic.AuditEvent; import java.io.File; @@ -60,7 +59,7 @@ public class AuditEventSaveTaskTest { @Before public void prepareTestFile() { - testFile = new File(Environment.getExternalStorageDirectory().getPath() + "/odk/instances/audit.csv"); + testFile = new File(Collect.INSTANCES_PATH + "/audit.csv"); testFile.delete(); } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/test/TestUtils.java b/collect_app/src/androidTest/java/org/odk/collect/android/test/TestUtils.java index 0aba8cf861e..78623070126 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/test/TestUtils.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/test/TestUtils.java @@ -1,6 +1,5 @@ package org.odk.collect.android.test; -import android.os.Environment; import androidx.test.espresso.PerformException; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; @@ -75,7 +74,7 @@ public static void cleanUpTempFiles() { } private static File tempFileDirectory() { - return new File(Environment.getExternalStorageDirectory(), "test-tmp"); + return new File(Collect.STORAGE, "test-tmp"); } public static void closeSafely(Closeable c) { diff --git a/collect_app/src/main/java/org/odk/collect/android/application/Collect.java b/collect_app/src/main/java/org/odk/collect/android/application/Collect.java index 98eab08693b..1e050d1549b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/application/Collect.java +++ b/collect_app/src/main/java/org/odk/collect/android/application/Collect.java @@ -88,8 +88,8 @@ public class Collect extends Application { // Storage paths - public static final String ODK_ROOT = Environment.getExternalStorageDirectory() - + File.separator + "odk"; + public static final String STORAGE = Environment.getExternalStorageDirectory().getAbsolutePath(); + public static final String ODK_ROOT = STORAGE + File.separator + "odk"; public static final String FORMS_PATH = ODK_ROOT + File.separator + "forms"; public static final String INSTANCES_PATH = ODK_ROOT + File.separator + "instances"; public static final String CACHE_PATH = ODK_ROOT + File.separator + ".cache"; diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java index 0ce2446e228..879fa8e2afc 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java @@ -22,7 +22,6 @@ import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; -import android.os.Environment; import org.apache.commons.io.IOUtils; import org.javarosa.xform.parse.XFormParser; @@ -621,10 +620,9 @@ public static File simplifyPath(File file) { if (isSdcardSymlinkSameAsExternalStorageDirectory) { // They point to the same place, so it's safe to replace the longer // storage path with the short symlink. - String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath(); String path = file.getAbsolutePath(); - if (path.startsWith(storagePath + "/")) { - return new File("/sdcard" + path.substring(storagePath.length())); + if (path.startsWith(Collect.STORAGE + "/")) { + return new File("/sdcard" + path.substring(Collect.STORAGE.length())); } } return file; @@ -642,7 +640,7 @@ private static void checkIfSdcardSymlinkSameAsExternalStorageDirectory() { File shortPathFile = File.createTempFile("odk", null, new File("/sdcard")); try { String name = shortPathFile.getName(); - File longPathFile = new File(Environment.getExternalStorageDirectory(), name); + File longPathFile = new File(Collect.STORAGE, name); // If we delete the file via one path and the file disappears at the // other path, then we know that both paths point to the same place. diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/VideoWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/VideoWidget.java index 57016bc84e9..c76b7d7cc75 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/VideoWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/VideoWidget.java @@ -23,7 +23,6 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; -import android.os.Environment; import android.preference.PreferenceManager; import android.provider.MediaStore.Video; import androidx.annotation.NonNull; @@ -152,8 +151,7 @@ public static File getOutputMediaFile(int type) { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. - File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), - DIRECTORY_PICTURES); + File mediaStorageDir = new File(Collect.STORAGE, DIRECTORY_PICTURES); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. From 93fe0591590c5d970944d7ce892560feb00cf902 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 13:39:02 +0100 Subject: [PATCH 02/12] Created InstanceUtils class and moved two util methods form InstancesDao there --- .../collect/android/dao/InstancesDaoTest.java | 33 ++++---- .../helpers/InstancesDatabaseHelperTest.java | 4 +- .../tasks/InstanceServerUploaderTaskTest.java | 3 +- .../utilities/InstanceUploaderUtilsTest.java | 2 +- .../odk/collect/android/dao/InstancesDao.java | 66 --------------- .../android/upload/AutoSendWorker.java | 6 +- .../android/upload/InstanceUploader.java | 6 +- .../android/utilities/InstanceUtils.java | 80 +++++++++++++++++++ 8 files changed, 108 insertions(+), 92 deletions(-) create mode 100644 collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java index 291bc982b02..7dede241313 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java @@ -29,6 +29,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; +import org.odk.collect.android.utilities.InstanceUtils; import java.util.List; @@ -66,7 +67,7 @@ public void setUp() { @Test public void getUnsentInstancesCursorTest() { Cursor cursor = instancesDao.getUnsentInstancesCursor(); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(4, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -78,7 +79,7 @@ public void getUnsentInstancesCursorTest() { @Test public void getSentInstancesCursorTest() { Cursor cursor = instancesDao.getSentInstancesCursor(); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -88,7 +89,7 @@ public void getSentInstancesCursorTest() { @Test public void getSavedInstancesCursorTest() { Cursor cursor = instancesDao.getSavedInstancesCursor(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME + " ASC"); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(5, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -101,7 +102,7 @@ public void getSavedInstancesCursorTest() { @Test public void getFinalizedInstancesCursorTest() { Cursor cursor = instancesDao.getFinalizedInstancesCursor(); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -110,7 +111,7 @@ public void getFinalizedInstancesCursorTest() { @Test public void getInstancesCursorForFilePathTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Hypertension Screening_2017-02-20_14-03-53/Hypertension Screening_2017-02-20_14-03-53.xml"); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(hypertensionScreeningInstance, instances.get(0)); @@ -119,7 +120,7 @@ public void getInstancesCursorForFilePathTest() { @Test public void getAllCompletedUndeletedInstancesCursorTest() { Cursor cursor = instancesDao.getAllCompletedUndeletedInstancesCursor(); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -129,7 +130,7 @@ public void getAllCompletedUndeletedInstancesCursorTest() { @Test public void getInstancesCursorForIdTest() { Cursor cursor = instancesDao.getInstancesCursorForId("2"); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -138,7 +139,7 @@ public void getInstancesCursorForIdTest() { @Test public void updateInstanceTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - List instances = instancesDao.getInstancesFromCursor(cursor); + List instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -154,11 +155,11 @@ public void updateInstanceTest() { String where = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + "=?"; String[] whereArgs = {Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"}; - assertEquals(instancesDao.updateInstance(instancesDao.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); + assertEquals(instancesDao.updateInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - instances = instancesDao.getInstancesFromCursor(cursor); + instances = InstanceUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -172,7 +173,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487595836793L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(hypertensionScreeningInstance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(hypertensionScreeningInstance)); cascadingSelectInstance = new Instance.Builder() .displayName("Cascading Select Form") @@ -181,7 +182,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596015000L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(cascadingSelectInstance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(cascadingSelectInstance)); biggestNOfSetInstance = new Instance.Builder() .displayName("Biggest N of Set") @@ -190,7 +191,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_SUBMITTED) .lastStatusChangeDate(1487596015100L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(biggestNOfSetInstance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSetInstance)); widgetsInstance = new Instance.Builder() .displayName("Widgets") @@ -200,7 +201,7 @@ private void fillDatabase() { .lastStatusChangeDate(1487596020803L) .deletedDate(1487596020803L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(widgetsInstance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(widgetsInstance)); sampleInstance = new Instance.Builder() .displayName("sample") @@ -209,7 +210,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596026373L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(sampleInstance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(sampleInstance)); biggestNOfSet2Instance = new Instance.Builder() .displayName("Biggest N of Set") @@ -218,7 +219,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(1487597090653L) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(biggestNOfSet2Instance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSet2Instance)); } @After diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java index 7f4cdcebfb4..d64d0f32c1c 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java @@ -10,6 +10,7 @@ import org.odk.collect.android.dao.InstancesDao; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.utilities.FileUtils; +import org.odk.collect.android.utilities.InstanceUtils; import org.odk.collect.android.utilities.SQLiteUtils; import java.io.File; @@ -69,8 +70,7 @@ public void testMigration() throws IOException { } private void assertThatInstancesAreKeptAfterMigrating() { - InstancesDao instancesDao = new InstancesDao(); - List instances = instancesDao.getInstancesFromCursor(instancesDao.getInstancesCursor(null, null)); + List instances = InstanceUtils.getInstancesFromCursor(new InstancesDao().getInstancesCursor(null, null)); assertEquals(2, instances.size()); assertEquals("complete", instances.get(0).getStatus()); assertEquals(Long.valueOf(1564413556249L), instances.get(0).getLastStatusChangeDate()); diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java index 319c9dba859..add613c8ea8 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java @@ -12,6 +12,7 @@ import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.test.MockedServerTest; +import org.odk.collect.android.utilities.InstanceUtils; import java.io.File; @@ -92,7 +93,7 @@ private long createStoredInstance() throws Exception { .lastStatusChangeDate(123L) .build(); - Uri contentUri = dao.saveInstance(dao.getValuesFromInstanceObject(i)); + Uri contentUri = dao.saveInstance(InstanceUtils.getValuesFromInstanceObject(i)); return Long.parseLong(contentUri.toString().substring(InstanceProviderAPI.InstanceColumns.CONTENT_URI.toString().length() + 1)); } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java index dc5a92c37fa..40e3dd3cc0e 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java @@ -60,7 +60,7 @@ private void fillTestDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(time) .build(); - instancesDao.saveInstance(instancesDao.getValuesFromInstanceObject(instance)); + instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(instance)); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java index bd2a6bc08e7..232a4eb0b07 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java @@ -22,11 +22,9 @@ import androidx.loader.content.CursorLoader; import org.odk.collect.android.application.Collect; -import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; -import java.util.ArrayList; import java.util.List; /** @@ -291,68 +289,4 @@ public void deleteInstancesFromIDs(List ids) { } } - - /** - * Returns all instances available through the cursor and closes the cursor. - */ - public List getInstancesFromCursor(Cursor cursor) { - List instances = new ArrayList<>(); - if (cursor != null) { - try { - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - int displayNameColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME); - int submissionUriColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI); - int canEditWhenCompleteIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE); - int instanceFilePathIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); - int jrFormIdColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_FORM_ID); - int jrVersionColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_VERSION); - int statusColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS); - int lastStatusChangeDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE); - int deletedDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DELETED_DATE); - - int databaseIdIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns._ID); - - Instance instance = new Instance.Builder() - .displayName(cursor.getString(displayNameColumnIndex)) - .submissionUri(cursor.getString(submissionUriColumnIndex)) - .canEditWhenComplete(cursor.getString(canEditWhenCompleteIndex)) - .instanceFilePath(cursor.getString(instanceFilePathIndex)) - .jrFormId(cursor.getString(jrFormIdColumnIndex)) - .jrVersion(cursor.getString(jrVersionColumnIndex)) - .status(cursor.getString(statusColumnIndex)) - .lastStatusChangeDate(cursor.getLong(lastStatusChangeDateColumnIndex)) - .deletedDate(cursor.getLong(deletedDateColumnIndex)) - .databaseId(cursor.getLong(databaseIdIndex)) - .build(); - - instances.add(instance); - } - } finally { - cursor.close(); - } - } - return instances; - } - - /** - * Returns the values of an instance as a ContentValues object for use with - * {@link #saveInstance(ContentValues)} or {@link #updateInstance(ContentValues, String, String[])} - * - * Does NOT include the database ID. - */ - public ContentValues getValuesFromInstanceObject(Instance instance) { - ContentValues values = new ContentValues(); - values.put(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME, instance.getDisplayName()); - values.put(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI, instance.getSubmissionUri()); - values.put(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE, instance.getCanEditWhenComplete()); - values.put(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH, instance.getInstanceFilePath()); - values.put(InstanceProviderAPI.InstanceColumns.JR_FORM_ID, instance.getJrFormId()); - values.put(InstanceProviderAPI.InstanceColumns.JR_VERSION, instance.getJrVersion()); - values.put(InstanceProviderAPI.InstanceColumns.STATUS, instance.getStatus()); - values.put(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE, instance.getLastStatusChangeDate()); - values.put(InstanceProviderAPI.InstanceColumns.DELETED_DATE, instance.getDeletedDate()); - - return values; - } } diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java index 47462dabc1b..4f724a042b1 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java @@ -41,6 +41,7 @@ import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; import org.odk.collect.android.utilities.InstanceUploaderUtils; +import org.odk.collect.android.utilities.InstanceUtils; import org.odk.collect.android.utilities.NotificationUtils; import org.odk.collect.android.utilities.PermissionUtils; import org.odk.collect.android.utilities.WebCredentialsUtils; @@ -199,9 +200,8 @@ private boolean networkTypeMatchesAutoSendSetting(NetworkInfo currentNetworkInfo */ @NonNull private List getInstancesToAutoSend(boolean isAutoSendAppSettingEnabled) { - InstancesDao dao = new InstancesDao(); - Cursor c = dao.getFinalizedInstancesCursor(); - List allFinalized = dao.getInstancesFromCursor(c); + Cursor c = new InstancesDao().getFinalizedInstancesCursor(); + List allFinalized = InstanceUtils.getInstancesFromCursor(c); List toUpload = new ArrayList<>(); for (Instance instance : allFinalized) { diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java index e09b7e34179..f3ab38221fd 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java @@ -26,6 +26,7 @@ import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; +import org.odk.collect.android.utilities.InstanceUtils; import java.util.ArrayList; import java.util.List; @@ -52,7 +53,6 @@ public abstract class InstanceUploader { */ public List getInstancesFromIds(Long... instanceDatabaseIds) { List instancesToUpload = new ArrayList<>(); - InstancesDao dao = new InstancesDao(); // Split the queries to avoid exceeding SQLITE_MAX_VARIABLE_NUMBER int counter = 0; @@ -76,8 +76,8 @@ public List getInstancesFromIds(Long... instanceDatabaseIds) { selectionBuf.append(')'); String selection = selectionBuf.toString(); - Cursor c = dao.getInstancesCursor(selection, selectionArgs); - instancesToUpload.addAll(dao.getInstancesFromCursor(c)); + Cursor c = new InstancesDao().getInstancesCursor(selection, selectionArgs); + instancesToUpload.addAll(InstanceUtils.getInstancesFromCursor(c)); counter++; } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java new file mode 100644 index 00000000000..bfa4288131a --- /dev/null +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java @@ -0,0 +1,80 @@ +package org.odk.collect.android.utilities; + +import android.content.ContentValues; +import android.database.Cursor; + +import org.odk.collect.android.dto.Instance; +import org.odk.collect.android.provider.InstanceProviderAPI; + +import java.util.ArrayList; +import java.util.List; + +public class InstanceUtils { + + private InstanceUtils() { } + + /** + * Returns all instances available through the cursor and closes the cursor. + */ + public static List getInstancesFromCursor(Cursor cursor) { + List instances = new ArrayList<>(); + if (cursor != null) { + try { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + int displayNameColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME); + int submissionUriColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI); + int canEditWhenCompleteIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE); + int instanceFilePathIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); + int jrFormIdColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_FORM_ID); + int jrVersionColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_VERSION); + int statusColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS); + int lastStatusChangeDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE); + int deletedDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DELETED_DATE); + + int databaseIdIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns._ID); + + Instance instance = new Instance.Builder() + .displayName(cursor.getString(displayNameColumnIndex)) + .submissionUri(cursor.getString(submissionUriColumnIndex)) + .canEditWhenComplete(cursor.getString(canEditWhenCompleteIndex)) + .instanceFilePath(cursor.getString(instanceFilePathIndex)) + .jrFormId(cursor.getString(jrFormIdColumnIndex)) + .jrVersion(cursor.getString(jrVersionColumnIndex)) + .status(cursor.getString(statusColumnIndex)) + .lastStatusChangeDate(cursor.getLong(lastStatusChangeDateColumnIndex)) + .deletedDate(cursor.getLong(deletedDateColumnIndex)) + .databaseId(cursor.getLong(databaseIdIndex)) + .build(); + + instances.add(instance); + } + } finally { + cursor.close(); + } + } + return instances; + } + + /** + * Returns the values of an instance as a ContentValues object for use with + * {@link org.odk.collect.android.dao.InstancesDao#saveInstance(ContentValues)} (ContentValues)} + * or {@link org.odk.collect.android.dao.InstancesDao#updateInstance(ContentValues, String, String[])} + * + * Does NOT include the database ID. + */ + public static ContentValues getValuesFromInstanceObject(Instance instance) { + ContentValues values = new ContentValues(); + values.put(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME, instance.getDisplayName()); + values.put(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI, instance.getSubmissionUri()); + values.put(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE, instance.getCanEditWhenComplete()); + values.put(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH, instance.getInstanceFilePath()); + values.put(InstanceProviderAPI.InstanceColumns.JR_FORM_ID, instance.getJrFormId()); + values.put(InstanceProviderAPI.InstanceColumns.JR_VERSION, instance.getJrVersion()); + values.put(InstanceProviderAPI.InstanceColumns.STATUS, instance.getStatus()); + values.put(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE, instance.getLastStatusChangeDate()); + values.put(InstanceProviderAPI.InstanceColumns.DELETED_DATE, instance.getDeletedDate()); + + return values; + } +} From af1b0955579d8862c0c6b10d3fa7fe04be462110 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 19:25:09 +0100 Subject: [PATCH 03/12] Fixed paths used in instances.db --- .../collect/android/dao/InstancesDaoTest.java | 21 ++++++++++++++++++ .../odk/collect/android/dao/InstancesDao.java | 22 +++++++++++-------- .../android/provider/InstanceProvider.java | 9 ++++---- .../collect/android/tasks/FormLoaderTask.java | 3 ++- .../android/tasks/InstanceSyncTask.java | 11 +++++----- .../collect/android/tasks/SaveToDiskTask.java | 15 ++++++------- .../collect/android/tasks/sms/SmsService.java | 2 +- .../android/utilities/InstanceUtils.java | 9 ++++++++ 8 files changed, 64 insertions(+), 28 deletions(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java index 7dede241313..dc9da5e336a 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java @@ -31,9 +31,11 @@ import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.InstanceUtils; +import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; @RunWith(AndroidJUnit4.class) /** @@ -165,6 +167,25 @@ public void updateInstanceTest() { assertEquals(biggestNOfSet2Instance, instances.get(0)); } + @Test + public void deleteInstancesTest() { + List instances = InstanceUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + assertEquals(6, instances.size()); + + List absoluteInstanceFilePaths = new ArrayList<>(); + absoluteInstanceFilePaths.add(Collect.INSTANCES_PATH + "/Hypertension Screening_2017-02-20_14-03-53/Hypertension Screening_2017-02-20_14-03-53.xml"); + absoluteInstanceFilePaths.add("/Biggest N of Set_2017-02-20_14-06-51/Biggest N of Set_2017-02-20_14-06-51.xml"); + instancesDao.deleteInstances(absoluteInstanceFilePaths); + + instances = InstanceUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + assertEquals(4, instances.size()); + + for (Instance instance : instances) { + assertFalse(instance.getInstanceFilePath().endsWith("Hypertension Screening_2017-02-20_14-03-53.xml")); + assertFalse(instance.getInstanceFilePath().endsWith("Biggest N of Set_2017-02-20_14-06-51.xml")); + } + } + private void fillDatabase() { hypertensionScreeningInstance = new Instance.Builder() .displayName("Hypertension Screening") diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java index 232a4eb0b07..caec4dd7f77 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java @@ -24,6 +24,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; +import org.odk.collect.android.utilities.InstanceUtils; import java.util.List; @@ -162,8 +163,8 @@ public CursorLoader getFinalizedInstancesCursorLoader(CharSequence charSequence, } public Cursor getInstancesCursorForFilePath(String path) { - String selection = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + "=?"; - String[] selectionArgs = {path}; + String selection = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; + String[] selectionArgs = {"%" + InstanceUtils.getRelativeInstanceFilePath(path)}; return getInstancesCursor(null, selection, selectionArgs, null); } @@ -224,6 +225,10 @@ public Cursor getInstancesCursorForId(String id) { return getInstancesCursor(null, selection, selectionArgs, null); } + public Cursor getInstancesCursor() { + return getInstancesCursor(null, null, null, null); + } + public Cursor getInstancesCursor(String selection, String[] selectionArgs) { return getInstancesCursor(null, selection, selectionArgs, null); } @@ -255,8 +260,8 @@ public void deleteInstancesDatabase() { Collect.getInstance().getContentResolver().delete(InstanceProviderAPI.InstanceColumns.CONTENT_URI, null, null); } - public void deleteInstancesFromIDs(List ids) { - int count = ids.size(); + public void deleteInstances(List absoluteInstanceFilePaths) { + int count = absoluteInstanceFilePaths.size(); int counter = 0; while (count > 0) { String[] selectionArgs = null; @@ -268,21 +273,20 @@ public void deleteInstancesFromIDs(List ids) { } StringBuilder selection = new StringBuilder(); - selection.append(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + " IN ("); + selection.append(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); int j = 0; while (j < selectionArgs.length) { - selectionArgs[j] = ids.get( + selectionArgs[j] = "%" + absoluteInstanceFilePaths.get( counter * ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER + j); - selection.append('?'); + selection.append(" LIKE ?"); if (j != selectionArgs.length - 1) { - selection.append(','); + selection.append(" OR " + InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); } j++; } counter++; count -= selectionArgs.length; - selection.append(')'); Collect.getInstance().getContentResolver() .delete(InstanceProviderAPI.InstanceColumns.CONTENT_URI, selection.toString(), selectionArgs); diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java index f25b0dfacb0..e0d75d025d1 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java @@ -32,6 +32,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.database.helpers.InstancesDatabaseHelper; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; +import org.odk.collect.android.utilities.InstanceUtils; import org.odk.collect.android.utilities.MediaUtils; import java.io.File; @@ -259,8 +260,8 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { if (del != null && del.getCount() > 0) { del.moveToFirst(); do { - String instanceFile = del.getString( - del.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH)); + String instanceFile = InstanceUtils.getAbsoluteInstanceFilePath(del.getString( + del.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); } while (del.moveToNext()); @@ -284,8 +285,8 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { c.moveToFirst(); status = c.getString(c.getColumnIndex(InstanceColumns.STATUS)); do { - String instanceFile = c.getString( - c.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH)); + String instanceFile = InstanceUtils.getAbsoluteInstanceFilePath(c.getString( + c.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); } while (c.moveToNext()); diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java index 769641314b9..7dd8612aff6 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java @@ -46,6 +46,7 @@ import org.odk.collect.android.logic.FormController; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.FormDefCache; +import org.odk.collect.android.utilities.InstanceUtils; import org.odk.collect.android.utilities.ZipUtils; import java.io.File; @@ -105,7 +106,7 @@ protected void free() { FECWrapper data; public FormLoaderTask(String instancePath, String xpath, String waitingXPath) { - this.instancePath = instancePath; + this.instancePath = InstanceUtils.getAbsoluteInstanceFilePath(instancePath); this.xpath = xpath; this.waitingXPath = waitingXPath; } diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java index a0ed537ad9a..7d53a08e9f3 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java @@ -33,6 +33,7 @@ import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.EncryptionUtils; +import org.odk.collect.android.utilities.InstanceUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -121,8 +122,8 @@ protected String doInBackground(Void... params) { instanceCursor.moveToPosition(-1); while (instanceCursor.moveToNext()) { - String instanceFilename = instanceCursor.getString( - instanceCursor.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH)); + String instanceFilename = InstanceUtils.getAbsoluteInstanceFilePath(instanceCursor.getString( + instanceCursor.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); String instanceStatus = instanceCursor.getString( instanceCursor.getColumnIndex(InstanceColumns.STATUS)); if (candidateInstances.contains(instanceFilename) || instanceStatus.equals(InstanceProviderAPI.STATUS_SUBMITTED)) { @@ -138,7 +139,7 @@ protected String doInBackground(Void... params) { } } - instancesDao.deleteInstancesFromIDs(filesToRemove); + instancesDao.deleteInstances(filesToRemove); final boolean instanceSyncFlag = PreferenceManager.getDefaultSharedPreferences( Collect.getInstance().getApplicationContext()).getBoolean( @@ -169,7 +170,7 @@ protected String doInBackground(Void... params) { // add missing fields into content values ContentValues values = new ContentValues(); - values.put(InstanceColumns.INSTANCE_FILE_PATH, candidateInstance); + values.put(InstanceColumns.INSTANCE_FILE_PATH, InstanceUtils.getRelativeInstanceFilePath(candidateInstance)); values.put(InstanceColumns.SUBMISSION_URI, submissionUri); values.put(InstanceColumns.DISPLAY_NAME, formName); values.put(InstanceColumns.JR_FORM_ID, jrFormId); @@ -262,7 +263,7 @@ private void encryptInstance(Cursor instanceCursor, String candidateInstance, EncryptionUtils.generateEncryptedSubmission(instanceXml, submissionXml, formInfo); values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE, Boolean.toString(false)); - instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + "=?", new String[]{candidateInstance}); + instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?", new String[]{"%" + InstanceUtils.getRelativeInstanceFilePath(candidateInstance)}); SaveToDiskTask.manageFilesAfterSavingEncryptedForm(instanceXml, submissionXml); if (!EncryptionUtils.deletePlaintextFiles(instanceXml, null)) { diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java index 86a308b1960..ffd4459a30a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java @@ -33,6 +33,7 @@ import org.odk.collect.android.utilities.EncryptionUtils; import org.odk.collect.android.utilities.EncryptionUtils.EncryptedFormInformation; import org.odk.collect.android.utilities.FileUtils; +import org.odk.collect.android.utilities.InstanceUtils; import org.odk.collect.android.utilities.MediaManager; import java.io.File; @@ -179,16 +180,14 @@ private void updateInstanceDatabase(boolean incomplete, boolean canEditAfterComp // However, it could be a not-first time saving if the user has been using the manual // 'save data' option from the menu. So try to update first, then make a new one if that // fails. - String instancePath = formController.getInstanceFile().getAbsolutePath(); - String where = InstanceColumns.INSTANCE_FILE_PATH + "=?"; - String[] whereArgs = { - instancePath - }; + String relativeInstancePath = InstanceUtils.getRelativeInstanceFilePath(formController.getAbsoluteInstancePath()); + String where = InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; + String[] whereArgs = {"%" + relativeInstancePath}; int updated = new InstancesDao().updateInstance(values, where, whereArgs); if (updated > 1) { - Timber.w("Updated more than one entry, that's not good: %s", instancePath); + Timber.w("Updated more than one entry, that's not good: %s", relativeInstancePath); } else if (updated == 1) { - Timber.i("Instance found and successfully updated: %s", instancePath); + Timber.i("Instance found and successfully updated: %s", relativeInstancePath); // already existed and updated just fine } else { Timber.i("No instance found, creating"); @@ -206,7 +205,7 @@ private void updateInstanceDatabase(boolean incomplete, boolean canEditAfterComp } // add missing fields into values - values.put(InstanceColumns.INSTANCE_FILE_PATH, instancePath); + values.put(InstanceColumns.INSTANCE_FILE_PATH, relativeInstancePath); values.put(InstanceColumns.SUBMISSION_URI, submissionUri); if (instanceName != null) { values.put(InstanceColumns.DISPLAY_NAME, instanceName); diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/sms/SmsService.java b/collect_app/src/main/java/org/odk/collect/android/tasks/sms/SmsService.java index 4efb808c5f0..f801bf1791b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/sms/SmsService.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/sms/SmsService.java @@ -336,7 +336,7 @@ private void markInstanceAsSubmittedOrDelete(String instanceId) { List instancesToDelete = new ArrayList<>(); instancesToDelete.add(instanceId); - instancesDao.deleteInstancesFromIDs(instancesToDelete); + instancesDao.deleteInstances(instancesToDelete); } else { instancesDao.updateInstance(contentValues, where, whereArgs); } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java index bfa4288131a..be82e845e51 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java @@ -3,6 +3,7 @@ import android.content.ContentValues; import android.database.Cursor; +import org.odk.collect.android.application.Collect; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; @@ -13,6 +14,14 @@ public class InstanceUtils { private InstanceUtils() { } + public static String getAbsoluteInstanceFilePath(String instancePath) { + return instancePath.startsWith(Collect.ODK_ROOT) ? instancePath : Collect.ODK_ROOT + instancePath; + } + + public static String getRelativeInstanceFilePath(String instancePath) { + return instancePath.substring(Collect.ODK_ROOT.length()); + } + /** * Returns all instances available through the cursor and closes the cursor. */ From 22b0f0c1bcd77e2b5bdeffba186d591fb4b116ab Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 19:46:39 +0100 Subject: [PATCH 04/12] Fixed paths used in itemsets.db --- .../collect/android/dao/InstancesDaoTest.java | 38 ++++++++-------- .../helpers/InstancesDatabaseHelperTest.java | 4 +- .../tasks/InstanceServerUploaderTaskTest.java | 4 +- .../utilities/InstanceUploaderUtilsTest.java | 2 +- .../odk/collect/android/dao/InstancesDao.java | 4 +- .../android/database/ItemsetDbAdapter.java | 45 +++++-------------- .../android/provider/InstanceProvider.java | 6 +-- .../collect/android/tasks/FormLoaderTask.java | 4 +- .../android/tasks/InstanceSyncTask.java | 8 ++-- .../collect/android/tasks/SaveToDiskTask.java | 4 +- .../android/upload/AutoSendWorker.java | 4 +- .../android/upload/InstanceUploader.java | 4 +- ...{InstanceUtils.java => DatabaseUtils.java} | 12 ++--- 13 files changed, 58 insertions(+), 81 deletions(-) rename collect_app/src/main/java/org/odk/collect/android/utilities/{InstanceUtils.java => DatabaseUtils.java} (92%) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java index dc9da5e336a..b533e6959d8 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java @@ -29,7 +29,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import java.util.ArrayList; import java.util.List; @@ -69,7 +69,7 @@ public void setUp() { @Test public void getUnsentInstancesCursorTest() { Cursor cursor = instancesDao.getUnsentInstancesCursor(); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(4, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -81,7 +81,7 @@ public void getUnsentInstancesCursorTest() { @Test public void getSentInstancesCursorTest() { Cursor cursor = instancesDao.getSentInstancesCursor(); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -91,7 +91,7 @@ public void getSentInstancesCursorTest() { @Test public void getSavedInstancesCursorTest() { Cursor cursor = instancesDao.getSavedInstancesCursor(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME + " ASC"); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(5, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -104,7 +104,7 @@ public void getSavedInstancesCursorTest() { @Test public void getFinalizedInstancesCursorTest() { Cursor cursor = instancesDao.getFinalizedInstancesCursor(); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -113,7 +113,7 @@ public void getFinalizedInstancesCursorTest() { @Test public void getInstancesCursorForFilePathTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Hypertension Screening_2017-02-20_14-03-53/Hypertension Screening_2017-02-20_14-03-53.xml"); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(hypertensionScreeningInstance, instances.get(0)); @@ -122,7 +122,7 @@ public void getInstancesCursorForFilePathTest() { @Test public void getAllCompletedUndeletedInstancesCursorTest() { Cursor cursor = instancesDao.getAllCompletedUndeletedInstancesCursor(); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -132,7 +132,7 @@ public void getAllCompletedUndeletedInstancesCursorTest() { @Test public void getInstancesCursorForIdTest() { Cursor cursor = instancesDao.getInstancesCursorForId("2"); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -141,7 +141,7 @@ public void getInstancesCursorForIdTest() { @Test public void updateInstanceTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - List instances = InstanceUtils.getInstancesFromCursor(cursor); + List instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -157,11 +157,11 @@ public void updateInstanceTest() { String where = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + "=?"; String[] whereArgs = {Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"}; - assertEquals(instancesDao.updateInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); + assertEquals(instancesDao.updateInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - instances = InstanceUtils.getInstancesFromCursor(cursor); + instances = DatabaseUtils.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -169,7 +169,7 @@ public void updateInstanceTest() { @Test public void deleteInstancesTest() { - List instances = InstanceUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + List instances = DatabaseUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); assertEquals(6, instances.size()); List absoluteInstanceFilePaths = new ArrayList<>(); @@ -177,7 +177,7 @@ public void deleteInstancesTest() { absoluteInstanceFilePaths.add("/Biggest N of Set_2017-02-20_14-06-51/Biggest N of Set_2017-02-20_14-06-51.xml"); instancesDao.deleteInstances(absoluteInstanceFilePaths); - instances = InstanceUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + instances = DatabaseUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); assertEquals(4, instances.size()); for (Instance instance : instances) { @@ -194,7 +194,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487595836793L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(hypertensionScreeningInstance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(hypertensionScreeningInstance)); cascadingSelectInstance = new Instance.Builder() .displayName("Cascading Select Form") @@ -203,7 +203,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596015000L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(cascadingSelectInstance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(cascadingSelectInstance)); biggestNOfSetInstance = new Instance.Builder() .displayName("Biggest N of Set") @@ -212,7 +212,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_SUBMITTED) .lastStatusChangeDate(1487596015100L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSetInstance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSetInstance)); widgetsInstance = new Instance.Builder() .displayName("Widgets") @@ -222,7 +222,7 @@ private void fillDatabase() { .lastStatusChangeDate(1487596020803L) .deletedDate(1487596020803L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(widgetsInstance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(widgetsInstance)); sampleInstance = new Instance.Builder() .displayName("sample") @@ -231,7 +231,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596026373L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(sampleInstance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(sampleInstance)); biggestNOfSet2Instance = new Instance.Builder() .displayName("Biggest N of Set") @@ -240,7 +240,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(1487597090653L) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(biggestNOfSet2Instance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSet2Instance)); } @After diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java index d64d0f32c1c..dd8c8588d92 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java @@ -10,7 +10,7 @@ import org.odk.collect.android.dao.InstancesDao; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.utilities.FileUtils; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.SQLiteUtils; import java.io.File; @@ -70,7 +70,7 @@ public void testMigration() throws IOException { } private void assertThatInstancesAreKeptAfterMigrating() { - List instances = InstanceUtils.getInstancesFromCursor(new InstancesDao().getInstancesCursor(null, null)); + List instances = DatabaseUtils.getInstancesFromCursor(new InstancesDao().getInstancesCursor(null, null)); assertEquals(2, instances.size()); assertEquals("complete", instances.get(0).getStatus()); assertEquals(Long.valueOf(1564413556249L), instances.get(0).getLastStatusChangeDate()); diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java index add613c8ea8..f3ec39b8f85 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java @@ -12,7 +12,7 @@ import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.test.MockedServerTest; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import java.io.File; @@ -93,7 +93,7 @@ private long createStoredInstance() throws Exception { .lastStatusChangeDate(123L) .build(); - Uri contentUri = dao.saveInstance(InstanceUtils.getValuesFromInstanceObject(i)); + Uri contentUri = dao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(i)); return Long.parseLong(contentUri.toString().substring(InstanceProviderAPI.InstanceColumns.CONTENT_URI.toString().length() + 1)); } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java index 40e3dd3cc0e..42b8336794d 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java @@ -60,7 +60,7 @@ private void fillTestDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(time) .build(); - instancesDao.saveInstance(InstanceUtils.getValuesFromInstanceObject(instance)); + instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(instance)); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java index caec4dd7f77..79f86d18ea8 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java @@ -24,7 +24,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import java.util.List; @@ -164,7 +164,7 @@ public CursorLoader getFinalizedInstancesCursorLoader(CharSequence charSequence, public Cursor getInstancesCursorForFilePath(String path) { String selection = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; - String[] selectionArgs = {"%" + InstanceUtils.getRelativeInstanceFilePath(path)}; + String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; return getInstancesCursor(null, selection, selectionArgs, null); } diff --git a/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java b/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java index 62e1e9a32d9..72c652cff6f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java +++ b/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java @@ -7,6 +7,7 @@ import android.database.sqlite.SQLiteOpenHelper; import org.odk.collect.android.application.Collect; +import org.odk.collect.android.utilities.DatabaseUtils; import java.math.BigInteger; import java.security.MessageDigest; @@ -45,7 +46,6 @@ private static class DatabaseHelper extends SQLiteOpenHelper { public void onCreate(SQLiteDatabase db) { // create table to keep track of the itemsets db.execSQL(CREATE_ITEMSET_TABLE); - } @Override @@ -116,7 +116,7 @@ public boolean createTable(String formHash, String pathHash, String[] columns, S ContentValues cv = new ContentValues(); cv.put(KEY_ITEMSET_HASH, formHash); - cv.put(KEY_PATH, path); + cv.put(KEY_PATH, DatabaseUtils.getRelativeFilePath(path)); db.insert(ITEMSET_TABLE, null, cv); return true; @@ -136,23 +136,6 @@ public boolean addRow(String tableName, String[] columns, String[] newRow) { return true; } - public boolean tableExists(String tableName) { - // select name from sqlite_master where type = 'table' - String selection = "type=? and name=?"; - String[] selectionArgs = { - "table", DATABASE_TABLE + tableName - }; - Cursor c = db.query("sqlite_master", null, selection, selectionArgs, - null, null, null); - boolean exists = false; - if (c.getCount() == 1) { - exists = true; - } - c.close(); - return exists; - - } - public void beginTransaction() { db.execSQL("BEGIN"); } @@ -171,18 +154,14 @@ public void dropTable(String pathHash, String path) { db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE + pathHash); // and remove the entry from the itemsets table - String where = KEY_PATH + "=?"; - String[] whereArgs = { - path - }; + String where = KEY_PATH + " LIKE ?"; + String[] whereArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; db.delete(ITEMSET_TABLE, where, whereArgs); } public Cursor getItemsets(String path) { - String selection = KEY_PATH + "=?"; - String[] selectionArgs = { - path - }; + String selection = KEY_PATH + " LIKE ?"; + String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; return db.query(ITEMSET_TABLE, null, selection, selectionArgs, null, null, null); } @@ -191,20 +170,18 @@ public void delete(String path) { if (c != null) { if (c.getCount() == 1) { c.moveToFirst(); - String table = getMd5FromString(c.getString(c.getColumnIndex(KEY_PATH))); + String table = getMd5FromString(DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(KEY_PATH)))); db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE + table); } c.close(); } - String where = KEY_PATH + "=?"; - String[] whereArgs = { - path - }; + String where = KEY_PATH + " LIKE ?"; + String[] whereArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; db.delete(ITEMSET_TABLE, where, whereArgs); } - public static String getMd5FromString(String toEncode) { + public static String getMd5FromString(String absoluteCsvPath) { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); @@ -213,7 +190,7 @@ public static String getMd5FromString(String toEncode) { return null; } - md.update(toEncode.getBytes()); + md.update(absoluteCsvPath.getBytes()); byte[] digest = md.digest(); BigInteger bigInt = new BigInteger(1, digest); return bigInt.toString(16); diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java index e0d75d025d1..28cedc816d3 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java @@ -32,7 +32,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.database.helpers.InstancesDatabaseHelper; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.MediaUtils; import java.io.File; @@ -260,7 +260,7 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { if (del != null && del.getCount() > 0) { del.moveToFirst(); do { - String instanceFile = InstanceUtils.getAbsoluteInstanceFilePath(del.getString( + String instanceFile = DatabaseUtils.getAbsoluteFilePath(del.getString( del.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); @@ -285,7 +285,7 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { c.moveToFirst(); status = c.getString(c.getColumnIndex(InstanceColumns.STATUS)); do { - String instanceFile = InstanceUtils.getAbsoluteInstanceFilePath(c.getString( + String instanceFile = DatabaseUtils.getAbsoluteFilePath(c.getString( c.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java index 7dd8612aff6..8e99a7e4fd7 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java @@ -46,7 +46,7 @@ import org.odk.collect.android.logic.FormController; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.FormDefCache; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.ZipUtils; import java.io.File; @@ -106,7 +106,7 @@ protected void free() { FECWrapper data; public FormLoaderTask(String instancePath, String xpath, String waitingXPath) { - this.instancePath = InstanceUtils.getAbsoluteInstanceFilePath(instancePath); + this.instancePath = DatabaseUtils.getAbsoluteFilePath(instancePath); this.xpath = xpath; this.waitingXPath = waitingXPath; } diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java index 7d53a08e9f3..edb17b2b29c 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java @@ -33,7 +33,7 @@ import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.EncryptionUtils; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -122,7 +122,7 @@ protected String doInBackground(Void... params) { instanceCursor.moveToPosition(-1); while (instanceCursor.moveToNext()) { - String instanceFilename = InstanceUtils.getAbsoluteInstanceFilePath(instanceCursor.getString( + String instanceFilename = DatabaseUtils.getAbsoluteFilePath(instanceCursor.getString( instanceCursor.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); String instanceStatus = instanceCursor.getString( instanceCursor.getColumnIndex(InstanceColumns.STATUS)); @@ -170,7 +170,7 @@ protected String doInBackground(Void... params) { // add missing fields into content values ContentValues values = new ContentValues(); - values.put(InstanceColumns.INSTANCE_FILE_PATH, InstanceUtils.getRelativeInstanceFilePath(candidateInstance)); + values.put(InstanceColumns.INSTANCE_FILE_PATH, DatabaseUtils.getRelativeFilePath(candidateInstance)); values.put(InstanceColumns.SUBMISSION_URI, submissionUri); values.put(InstanceColumns.DISPLAY_NAME, formName); values.put(InstanceColumns.JR_FORM_ID, jrFormId); @@ -263,7 +263,7 @@ private void encryptInstance(Cursor instanceCursor, String candidateInstance, EncryptionUtils.generateEncryptedSubmission(instanceXml, submissionXml, formInfo); values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE, Boolean.toString(false)); - instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?", new String[]{"%" + InstanceUtils.getRelativeInstanceFilePath(candidateInstance)}); + instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?", new String[]{"%" + DatabaseUtils.getRelativeFilePath(candidateInstance)}); SaveToDiskTask.manageFilesAfterSavingEncryptedForm(instanceXml, submissionXml); if (!EncryptionUtils.deletePlaintextFiles(instanceXml, null)) { diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java index ffd4459a30a..9849f425870 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java @@ -33,7 +33,7 @@ import org.odk.collect.android.utilities.EncryptionUtils; import org.odk.collect.android.utilities.EncryptionUtils.EncryptedFormInformation; import org.odk.collect.android.utilities.FileUtils; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.MediaManager; import java.io.File; @@ -180,7 +180,7 @@ private void updateInstanceDatabase(boolean incomplete, boolean canEditAfterComp // However, it could be a not-first time saving if the user has been using the manual // 'save data' option from the menu. So try to update first, then make a new one if that // fails. - String relativeInstancePath = InstanceUtils.getRelativeInstanceFilePath(formController.getAbsoluteInstancePath()); + String relativeInstancePath = DatabaseUtils.getRelativeFilePath(formController.getAbsoluteInstancePath()); String where = InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; String[] whereArgs = {"%" + relativeInstancePath}; int updated = new InstancesDao().updateInstance(values, where, whereArgs); diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java index 4f724a042b1..4debfe328bb 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java @@ -41,7 +41,7 @@ import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; import org.odk.collect.android.utilities.InstanceUploaderUtils; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.NotificationUtils; import org.odk.collect.android.utilities.PermissionUtils; import org.odk.collect.android.utilities.WebCredentialsUtils; @@ -201,7 +201,7 @@ private boolean networkTypeMatchesAutoSendSetting(NetworkInfo currentNetworkInfo @NonNull private List getInstancesToAutoSend(boolean isAutoSendAppSettingEnabled) { Cursor c = new InstancesDao().getFinalizedInstancesCursor(); - List allFinalized = InstanceUtils.getInstancesFromCursor(c); + List allFinalized = DatabaseUtils.getInstancesFromCursor(c); List toUpload = new ArrayList<>(); for (Instance instance : allFinalized) { diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java index f3ab38221fd..b220014d0a3 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java @@ -26,7 +26,7 @@ import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; -import org.odk.collect.android.utilities.InstanceUtils; +import org.odk.collect.android.utilities.DatabaseUtils; import java.util.ArrayList; import java.util.List; @@ -77,7 +77,7 @@ public List getInstancesFromIds(Long... instanceDatabaseIds) { String selection = selectionBuf.toString(); Cursor c = new InstancesDao().getInstancesCursor(selection, selectionArgs); - instancesToUpload.addAll(InstanceUtils.getInstancesFromCursor(c)); + instancesToUpload.addAll(DatabaseUtils.getInstancesFromCursor(c)); counter++; } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java similarity index 92% rename from collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java rename to collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java index be82e845e51..8f038f8b4f7 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/InstanceUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java @@ -10,16 +10,16 @@ import java.util.ArrayList; import java.util.List; -public class InstanceUtils { +public class DatabaseUtils { - private InstanceUtils() { } + private DatabaseUtils() { } - public static String getAbsoluteInstanceFilePath(String instancePath) { - return instancePath.startsWith(Collect.ODK_ROOT) ? instancePath : Collect.ODK_ROOT + instancePath; + public static String getAbsoluteFilePath(String filePath) { + return filePath.startsWith(Collect.ODK_ROOT) ? filePath : Collect.ODK_ROOT + filePath; } - public static String getRelativeInstanceFilePath(String instancePath) { - return instancePath.substring(Collect.ODK_ROOT.length()); + public static String getRelativeFilePath(String filePath) { + return filePath.substring(Collect.ODK_ROOT.length()); } /** From 86dd5e5d6e9b814a42d5a0be53ca88145354548f Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 19:51:30 +0100 Subject: [PATCH 05/12] Moved some code from FormsDao class to DatabaseUtils --- .../odk/collect/android/dao/FormsDaoTest.java | 33 ++++---- .../helpers/FormsDatabaseHelperTest.java | 4 +- .../org/odk/collect/android/dao/FormsDao.java | 77 ------------------- .../InstanceGoogleSheetsUploaderTask.java | 6 +- .../android/upload/AutoSendWorker.java | 6 +- .../upload/InstanceGoogleSheetsUploader.java | 6 +- .../android/utilities/DatabaseUtils.java | 74 ++++++++++++++++++ 7 files changed, 101 insertions(+), 105 deletions(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java index 20f35d4bf26..0e02e348fd2 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java @@ -27,6 +27,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.dto.Form; import org.odk.collect.android.provider.FormsProviderAPI; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.ResetUtility; import java.io.File; @@ -64,7 +65,7 @@ public void setUp() throws IOException { @Test public void getAllFormsCursorTest() { Cursor cursor = formsDao.getFormsCursor(); - List
forms = formsDao.getFormsFromCursor(cursor); + List forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(0)); @@ -79,7 +80,7 @@ public void getAllFormsCursorTest() { @Test public void getFormsCursorForFormIdTest() { Cursor cursor = formsDao.getFormsCursorForFormId("Birds"); - List forms = formsDao.getFormsFromCursor(cursor); + List forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(2, forms.size()); assertEquals(birdsForm, forms.get(0)); @@ -88,7 +89,7 @@ public void getFormsCursorForFormIdTest() { @Test public void getFormsCursorTest() { Cursor cursor = formsDao.getFormsCursor(null, null, null, null); - List forms = formsDao.getFormsFromCursor(cursor); + List forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(0)); @@ -102,7 +103,7 @@ public void getFormsCursorTest() { String sortOrder = FormsProviderAPI.FormsColumns.DISPLAY_NAME + " COLLATE NOCASE DESC"; cursor = formsDao.getFormsCursor(null, null, null, sortOrder); - forms = formsDao.getFormsFromCursor(cursor); + forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(6)); @@ -117,7 +118,7 @@ public void getFormsCursorTest() { String[] selectionArgs = {"Miramare"}; cursor = formsDao.getFormsCursor(null, selection, selectionArgs, null); - forms = formsDao.getFormsFromCursor(cursor); + forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(miramareForm, forms.get(0)); @@ -126,7 +127,7 @@ public void getFormsCursorTest() { @Test public void getFormsCursorForFormFilePathTest() { Cursor cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Miramare.xml"); - List forms = formsDao.getFormsFromCursor(cursor); + List forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(miramareForm, forms.get(0)); @@ -135,7 +136,7 @@ public void getFormsCursorForFormFilePathTest() { @Test public void updateInstanceTest() { Cursor cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Widgets.xml"); - List forms = formsDao.getFormsFromCursor(cursor); + List forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(widgetsForm, forms.get(0)); @@ -152,10 +153,10 @@ public void updateInstanceTest() { String where = FormsProviderAPI.FormsColumns.DISPLAY_NAME + "=?"; String[] whereArgs = {"Widgets"}; - assertEquals(formsDao.updateForm(formsDao.getValuesFromFormObject(widgetsForm), where, whereArgs), 1); + assertEquals(formsDao.updateForm(DatabaseUtils.getValuesFromFormObject(widgetsForm), where, whereArgs), 1); cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Widgets.xml"); - forms = formsDao.getFormsFromCursor(cursor); + forms = DatabaseUtils.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(widgetsForm, forms.get(0)); @@ -179,7 +180,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/ccce6015dd1b8f935f5f3058e81eeb43.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(biggestNOfSetForm)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(biggestNOfSetForm)); assertTrue(new File(Collect.FORMS_PATH + "/Birds.xml").createNewFile()); birdsForm = new Form.Builder() @@ -193,7 +194,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4cd980d50f884362afba842cbff3a798.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(birdsForm)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(birdsForm)); assertTrue(new File(Collect.FORMS_PATH + "/Miramare.xml").createNewFile()); miramareForm = new Form.Builder() @@ -206,7 +207,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/e733627cdbf220929bf9c4899cb983ea.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(miramareForm)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(miramareForm)); assertTrue(new File(Collect.FORMS_PATH + "/Geo Tagger v2.xml").createNewFile()); geoTaggerV2Form = new Form.Builder() @@ -219,7 +220,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/1d5e9109298c8ef02bc523b17d7c0451.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(geoTaggerV2Form)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(geoTaggerV2Form)); assertTrue(new File(Collect.FORMS_PATH + "/Widgets.xml").createNewFile()); widgetsForm = new Form.Builder() @@ -232,7 +233,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/0eacc6333449e66826326eb5fcc75749.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(widgetsForm)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(widgetsForm)); assertTrue(new File(Collect.FORMS_PATH + "/sample.xml").createNewFile()); sampleForm = new Form.Builder() @@ -245,7 +246,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4f495fddd1f2544f65444ea83d25f425.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(sampleForm)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(sampleForm)); assertTrue(new File(Collect.FORMS_PATH + "/Birds_4.xml").createNewFile()); birds2Form = new Form.Builder() @@ -259,7 +260,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4cd980d50f884362afba842cbff3a775.formdef") .build(); - formsDao.saveForm(formsDao.getValuesFromFormObject(birds2Form)); + formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(birds2Form)); } @After diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java index f6e8f9e242e..339b21a6855 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java @@ -9,6 +9,7 @@ import org.junit.runners.Parameterized; import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.dto.Form; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.SQLiteUtils; @@ -80,8 +81,7 @@ public void testMigration() throws IOException { } private void assertThatFormsAreKeptAfterUpgrading() { - FormsDao formsDao = new FormsDao(); - List forms = formsDao.getFormsFromCursor(formsDao.getFormsCursor()); + List forms = DatabaseUtils.getFormsFromCursor(new FormsDao().getFormsCursor()); assertEquals(1, forms.size()); assertEquals("2019051302", forms.get(0).getJrVersion()); assertEquals("92ba8106dcb779943c1de163d73e1069", forms.get(0).getMD5Hash()); diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java index 76b8aefd0ee..2e0ad574e05 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java @@ -19,11 +19,9 @@ import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; -import android.provider.BaseColumns; import androidx.loader.content.CursorLoader; import org.odk.collect.android.application.Collect; -import org.odk.collect.android.dto.Form; import org.odk.collect.android.provider.FormsProviderAPI; import java.util.ArrayList; @@ -218,82 +216,7 @@ public Uri saveForm(ContentValues values) { return Collect.getInstance().getContentResolver().insert(FormsProviderAPI.FormsColumns.CONTENT_URI, values); } - public int updateForm(ContentValues values) { - return updateForm(values, null, null); - } - public int updateForm(ContentValues values, String where, String[] whereArgs) { return Collect.getInstance().getContentResolver().update(FormsProviderAPI.FormsColumns.CONTENT_URI, values, where, whereArgs); } - - /** - * Returns all forms available through the cursor and closes the cursor. - */ - public List getFormsFromCursor(Cursor cursor) { - List forms = new ArrayList<>(); - if (cursor != null) { - try { - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - int idColumnIndex = cursor.getColumnIndex(BaseColumns._ID); - int displayNameColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DISPLAY_NAME); - int descriptionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DESCRIPTION); - int jrFormIdColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_FORM_ID); - int jrVersionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_VERSION); - int formFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH); - int submissionUriColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.SUBMISSION_URI); - int base64RSAPublicKeyColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY); - int md5HashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.MD5_HASH); - int dateColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DATE); - int jrCacheFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH); - int formMediaPathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH); - int languageColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LANGUAGE); - int autoSendColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_SEND); - int autoDeleteColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_DELETE); - int lastDetectedFormVersionHashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LAST_DETECTED_FORM_VERSION_HASH); - - Form form = new Form.Builder() - .id(cursor.getInt(idColumnIndex)) - .displayName(cursor.getString(displayNameColumnIndex)) - .description(cursor.getString(descriptionColumnIndex)) - .jrFormId(cursor.getString(jrFormIdColumnIndex)) - .jrVersion(cursor.getString(jrVersionColumnIndex)) - .formFilePath(cursor.getString(formFilePathColumnIndex)) - .submissionUri(cursor.getString(submissionUriColumnIndex)) - .base64RSAPublicKey(cursor.getString(base64RSAPublicKeyColumnIndex)) - .md5Hash(cursor.getString(md5HashColumnIndex)) - .date(cursor.getLong(dateColumnIndex)) - .jrCacheFilePath(cursor.getString(jrCacheFilePathColumnIndex)) - .formMediaPath(cursor.getString(formMediaPathColumnIndex)) - .language(cursor.getString(languageColumnIndex)) - .autoSend(cursor.getString(autoSendColumnIndex)) - .autoDelete(cursor.getString(autoDeleteColumnIndex)) - .lastDetectedFormVersionHash(cursor.getString(lastDetectedFormVersionHashColumnIndex)) - .build(); - - forms.add(form); - } - } finally { - cursor.close(); - } - } - return forms; - } - - public ContentValues getValuesFromFormObject(Form form) { - ContentValues values = new ContentValues(); - values.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, form.getDisplayName()); - values.put(FormsProviderAPI.FormsColumns.DESCRIPTION, form.getDescription()); - values.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, form.getJrFormId()); - values.put(FormsProviderAPI.FormsColumns.JR_VERSION, form.getJrVersion()); - values.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, form.getFormFilePath()); - values.put(FormsProviderAPI.FormsColumns.SUBMISSION_URI, form.getSubmissionUri()); - values.put(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY, form.getBASE64RSAPublicKey()); - values.put(FormsProviderAPI.FormsColumns.MD5_HASH, form.getMD5Hash()); - values.put(FormsProviderAPI.FormsColumns.DATE, form.getDate()); - values.put(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH, form.getJrCacheFilePath()); - values.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, form.getFormMediaPath()); - values.put(FormsProviderAPI.FormsColumns.LANGUAGE, form.getLanguage()); - return values; - } } diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java index 1379cf5dcd4..1cdeaea4444 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java @@ -23,6 +23,7 @@ import org.odk.collect.android.dto.Instance; import org.odk.collect.android.upload.InstanceGoogleSheetsUploader; import org.odk.collect.android.upload.UploadException; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.InstanceUploaderUtils; import org.odk.collect.android.utilities.gdrive.GoogleAccountsManager; @@ -59,9 +60,8 @@ protected Outcome doInBackground(Long... instanceIdsToUpload) { publishProgress(i + 1, instancesToUpload.size()); // Get corresponding blank form and verify there is exactly 1 - FormsDao dao = new FormsDao(); - Cursor formCursor = dao.getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); - List forms = dao.getFormsFromCursor(formCursor); + Cursor formCursor = new FormsDao().getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); + List forms = DatabaseUtils.getFormsFromCursor(formCursor); if (forms.size() != 1) { outcome.messagesByInstanceId.put(instance.getDatabaseId().toString(), diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java index 4debfe328bb..5c3819c50ac 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java @@ -245,10 +245,8 @@ public static boolean formShouldBeAutoSent(String jrFormId, boolean isAutoSendAp * TODO: figure out where this should live */ private boolean atLeastOneFormSpecifiesAutoSend() { - FormsDao dao = new FormsDao(); - - try (Cursor cursor = dao.getFormsCursor()) { - List forms = dao.getFormsFromCursor(cursor); + try (Cursor cursor = new FormsDao().getFormsCursor()) { + List forms = DatabaseUtils.getFormsFromCursor(cursor); for (Form form : forms) { if (Boolean.valueOf(form.getAutoSend())) { return true; diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java index a68ec15d675..9437edaf15a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java @@ -41,6 +41,7 @@ import org.odk.collect.android.preferences.GeneralKeys; import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.tasks.FormLoaderTask; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.TextUtils; import org.odk.collect.android.utilities.UrlUtils; @@ -95,9 +96,8 @@ public String uploadOneSubmission(Instance instance, String spreadsheetUrl) thro } // Get corresponding blank form and verify there is exactly 1 - FormsDao dao = new FormsDao(); - Cursor formCursor = dao.getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); - List forms = dao.getFormsFromCursor(formCursor); + Cursor formCursor = new FormsDao().getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); + List forms = DatabaseUtils.getFormsFromCursor(formCursor); try { if (forms.size() != 1) { diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java index 8f038f8b4f7..13b57a3da3f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java @@ -2,9 +2,12 @@ import android.content.ContentValues; import android.database.Cursor; +import android.provider.BaseColumns; import org.odk.collect.android.application.Collect; +import org.odk.collect.android.dto.Form; import org.odk.collect.android.dto.Instance; +import org.odk.collect.android.provider.FormsProviderAPI; import org.odk.collect.android.provider.InstanceProviderAPI; import java.util.ArrayList; @@ -86,4 +89,75 @@ public static ContentValues getValuesFromInstanceObject(Instance instance) { return values; } + + /** + * Returns all forms available through the cursor and closes the cursor. + */ + public static List getFormsFromCursor(Cursor cursor) { + List forms = new ArrayList<>(); + if (cursor != null) { + try { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + int idColumnIndex = cursor.getColumnIndex(BaseColumns._ID); + int displayNameColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DISPLAY_NAME); + int descriptionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DESCRIPTION); + int jrFormIdColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_FORM_ID); + int jrVersionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_VERSION); + int formFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH); + int submissionUriColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.SUBMISSION_URI); + int base64RSAPublicKeyColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY); + int md5HashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.MD5_HASH); + int dateColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DATE); + int jrCacheFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH); + int formMediaPathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH); + int languageColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LANGUAGE); + int autoSendColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_SEND); + int autoDeleteColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_DELETE); + int lastDetectedFormVersionHashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LAST_DETECTED_FORM_VERSION_HASH); + + Form form = new Form.Builder() + .id(cursor.getInt(idColumnIndex)) + .displayName(cursor.getString(displayNameColumnIndex)) + .description(cursor.getString(descriptionColumnIndex)) + .jrFormId(cursor.getString(jrFormIdColumnIndex)) + .jrVersion(cursor.getString(jrVersionColumnIndex)) + .formFilePath(cursor.getString(formFilePathColumnIndex)) + .submissionUri(cursor.getString(submissionUriColumnIndex)) + .base64RSAPublicKey(cursor.getString(base64RSAPublicKeyColumnIndex)) + .md5Hash(cursor.getString(md5HashColumnIndex)) + .date(cursor.getLong(dateColumnIndex)) + .jrCacheFilePath(cursor.getString(jrCacheFilePathColumnIndex)) + .formMediaPath(cursor.getString(formMediaPathColumnIndex)) + .language(cursor.getString(languageColumnIndex)) + .autoSend(cursor.getString(autoSendColumnIndex)) + .autoDelete(cursor.getString(autoDeleteColumnIndex)) + .lastDetectedFormVersionHash(cursor.getString(lastDetectedFormVersionHashColumnIndex)) + .build(); + + forms.add(form); + } + } finally { + cursor.close(); + } + } + return forms; + } + + public static ContentValues getValuesFromFormObject(Form form) { + ContentValues values = new ContentValues(); + values.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, form.getDisplayName()); + values.put(FormsProviderAPI.FormsColumns.DESCRIPTION, form.getDescription()); + values.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, form.getJrFormId()); + values.put(FormsProviderAPI.FormsColumns.JR_VERSION, form.getJrVersion()); + values.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, form.getFormFilePath()); + values.put(FormsProviderAPI.FormsColumns.SUBMISSION_URI, form.getSubmissionUri()); + values.put(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY, form.getBASE64RSAPublicKey()); + values.put(FormsProviderAPI.FormsColumns.MD5_HASH, form.getMD5Hash()); + values.put(FormsProviderAPI.FormsColumns.DATE, form.getDate()); + values.put(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH, form.getJrCacheFilePath()); + values.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, form.getFormMediaPath()); + values.put(FormsProviderAPI.FormsColumns.LANGUAGE, form.getLanguage()); + return values; + } } From 3eb43dbab669e0421f9fcc822f6db58841e5be8b Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 20:11:00 +0100 Subject: [PATCH 06/12] Fixed paths used in forms.db JRCACHE_FILE_PATH --- .../odk/collect/android/provider/FormsProvider.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java index 64b689952ac..7ef622f02a1 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java @@ -31,6 +31,7 @@ import org.odk.collect.android.database.ItemsetDbAdapter; import org.odk.collect.android.database.helpers.FormsDatabaseHelper; import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.MediaUtils; @@ -200,9 +201,8 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { values.put(FormsColumns.MD5_HASH, md5); if (!values.containsKey(FormsColumns.JRCACHE_FILE_PATH)) { - String cachePath = Collect.CACHE_PATH + File.separator + md5 - + ".formdef"; - values.put(FormsColumns.JRCACHE_FILE_PATH, cachePath); + String cachePath = Collect.CACHE_PATH + File.separator + md5 + ".formdef"; + values.put(FormsColumns.JRCACHE_FILE_PATH, DatabaseUtils.getRelativeFilePath(cachePath)); } if (!values.containsKey(FormsColumns.FORM_MEDIA_PATH)) { values.put(FormsColumns.FORM_MEDIA_PATH, FileUtils.constructMediaPath(filePath)); @@ -244,7 +244,7 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { } private void deleteFileOrDir(String fileName) { - File file = new File(fileName); + File file = new File(DatabaseUtils.getAbsoluteFilePath(fileName)); if (file.exists()) { if (file.isDirectory()) { // delete any media entries for files in this directory... @@ -482,8 +482,7 @@ public int update(Uri uri, ContentValues values, String where, .getMd5Hash(new File(formFile)); values.put(FormsColumns.MD5_HASH, newMd5); values.put(FormsColumns.JRCACHE_FILE_PATH, - Collect.CACHE_PATH + File.separator + newMd5 - + ".formdef"); + DatabaseUtils.getRelativeFilePath(Collect.CACHE_PATH + File.separator + newMd5 + ".formdef")); } count = db.update( From 7fdbc9ecc57b429961a8e833ae3f0bddbd63d58f Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 20:30:16 +0100 Subject: [PATCH 07/12] Fixed paths used in forms.db FORM_MEDIA_PATH --- .../java/org/odk/collect/android/provider/FormsProvider.java | 2 +- .../odk/collect/android/utilities/DownloadFormListUtils.java | 2 +- .../org/odk/collect/android/utilities/FormDownloader.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java index 7ef622f02a1..ae73ff2addf 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java @@ -205,7 +205,7 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { values.put(FormsColumns.JRCACHE_FILE_PATH, DatabaseUtils.getRelativeFilePath(cachePath)); } if (!values.containsKey(FormsColumns.FORM_MEDIA_PATH)) { - values.put(FormsColumns.FORM_MEDIA_PATH, FileUtils.constructMediaPath(filePath)); + values.put(FormsColumns.FORM_MEDIA_PATH, DatabaseUtils.getRelativeFilePath(FileUtils.constructMediaPath(filePath))); } SQLiteDatabase db = formsDatabaseHelper.getWritableDatabase(); diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java index d9669889170..f3a4da5cd9f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java @@ -443,7 +443,7 @@ private boolean isNewerFormVersionAvailable(String md5Hash) { } private boolean areNewerMediaFilesAvailable(String formId, String formVersion, List newMediaFiles) { - String mediaDirPath = formsDao.getFormMediaPath(formId, formVersion); + String mediaDirPath = DatabaseUtils.getAbsoluteFilePath(formsDao.getFormMediaPath(formId, formVersion)); if (mediaDirPath != null) { File[] localMediaFiles = new File(mediaDirPath).listFiles(); if (localMediaFiles != null) { diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java index a766b1952dd..32a981a983d 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java @@ -303,7 +303,7 @@ private UriResult findExistingOrCreateNewUri(File formFile, Map private Uri saveNewForm(Map formInfo, File formFile, String mediaPath) { final ContentValues v = new ContentValues(); v.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, formFile.getAbsolutePath()); - v.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, mediaPath); + v.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, DatabaseUtils.getRelativeFilePath(mediaPath)); v.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, formInfo.get(FileUtils.TITLE)); v.put(FormsProviderAPI.FormsColumns.JR_VERSION, formInfo.get(FileUtils.VERSION)); v.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, formInfo.get(FileUtils.FORMID)); @@ -480,7 +480,7 @@ private static class UriResult { private UriResult(Uri uri, String mediaPath, boolean isNew) { this.uri = uri; - this.mediaPath = mediaPath; + this.mediaPath = DatabaseUtils.getAbsoluteFilePath(mediaPath); this.isNew = isNew; } From 30f26622e4afe43c6654a07fb23cfb3c9a0dd616 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 21:22:03 +0100 Subject: [PATCH 08/12] Fixed paths used in forms.db FORM_FILE_PATH --- .../android/activities/FormEntryActivity.java | 11 +++---- .../org/odk/collect/android/dao/FormsDao.java | 5 +-- .../dao/helpers/ContentResolverHelper.java | 3 +- .../android/dao/helpers/FormsDaoHelper.java | 5 +-- .../android/provider/FormsProvider.java | 31 +++++++++---------- .../collect/android/tasks/DiskSyncTask.java | 10 +++--- .../android/utilities/FormDownloader.java | 4 +-- 7 files changed, 35 insertions(+), 34 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java b/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java index ec815abe307..3f5ce2e69a2 100644 --- a/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java +++ b/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java @@ -134,6 +134,7 @@ import org.odk.collect.android.tasks.SaveToDiskTask; import org.odk.collect.android.upload.AutoSendWorker; import org.odk.collect.android.utilities.ApplicationConstants; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.DestroyableLifecyleOwner; import org.odk.collect.android.utilities.DialogUtils; import org.odk.collect.android.utilities.FileUtils; @@ -527,7 +528,7 @@ private void loadFromIntent(Intent intent) { EXIT); return; } else { - formPath = FormsDaoHelper.getFormPath(selection, selectionArgs); + formPath = FormsDaoHelper.getAbsoluteFormPath(selection, selectionArgs); /** * Still take the first entry, but warn that there are multiple rows. User will @@ -2013,11 +2014,9 @@ public void onClick(DialogInterface dialog, // when selecting a new // language ContentValues values = new ContentValues(); - values.put(FormsColumns.LANGUAGE, - languages[whichButton]); - String selection = FormsColumns.FORM_FILE_PATH - + "=?"; - String[] selectArgs = {formPath}; + values.put(FormsColumns.LANGUAGE, languages[whichButton]); + String selection = FormsColumns.FORM_FILE_PATH + " LIKE ?"; + String[] selectArgs = {"%" + DatabaseUtils.getRelativeFilePath(formPath)}; int updated = new FormsDao().updateForm(values, selection, selectArgs); Timber.i("Updated language to: %s in %d rows", languages[whichButton], diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java index 2e0ad574e05..b1cb8afb0f5 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java @@ -23,6 +23,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.provider.FormsProviderAPI; +import org.odk.collect.android.utilities.DatabaseUtils; import java.util.ArrayList; import java.util.List; @@ -163,8 +164,8 @@ public String getFormMediaPath(String formId, String formVersion) { } public Cursor getFormsCursorForFormFilePath(String formFilePath) { - String selection = FormsProviderAPI.FormsColumns.FORM_FILE_PATH + "=?"; - String[] selectionArgs = {formFilePath}; + String selection = FormsProviderAPI.FormsColumns.FORM_FILE_PATH + " LIKE ?"; + String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(formFilePath)}; return getFormsCursor(null, selection, selectionArgs, null); } diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java index d801a0c6402..f5e37f99297 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java @@ -25,6 +25,7 @@ import org.odk.collect.android.logic.FormInfo; import org.odk.collect.android.provider.FormsProviderAPI; import org.odk.collect.android.provider.InstanceProviderAPI; +import org.odk.collect.android.utilities.DatabaseUtils; public final class ContentResolverHelper { @@ -67,7 +68,7 @@ public static String getFormPath(Uri uri) { try (Cursor c = getContentResolver().query(uri, null, null, null, null)) { if (c != null && c.getCount() == 1) { c.moveToFirst(); - formPath = c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH)); + formPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); } } return formPath; diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java index 1ae699e1dca..1721a165b8c 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java @@ -18,6 +18,7 @@ import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.provider.FormsProviderAPI; +import org.odk.collect.android.utilities.DatabaseUtils; public final class FormsDaoHelper { @@ -35,13 +36,13 @@ public static int getFormsCount(String selection, String[] selectionArgs) { throw new RuntimeException("Unable to get the forms count"); } - public static String getFormPath(String selection, String[] selectionArgs) { + public static String getAbsoluteFormPath(String selection, String[] selectionArgs) { FormsDao formsDao = new FormsDao(); String formPath = null; try (Cursor c = formsDao.getFormsCursor(selection, selectionArgs)) { if (c != null && c.getCount() > 0) { c.moveToFirst(); - formPath = c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH)); + formPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); } } return formPath; diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java index ae73ff2addf..ab0b5a0670e 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java @@ -177,10 +177,10 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { // Normalize the file path. // (don't trust the requester). - String filePath = values.getAsString(FormsColumns.FORM_FILE_PATH); + String filePath = DatabaseUtils.getAbsoluteFilePath(values.getAsString(FormsColumns.FORM_FILE_PATH)); File form = new File(filePath); filePath = form.getAbsolutePath(); // normalized - values.put(FormsColumns.FORM_FILE_PATH, filePath); + values.put(FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(filePath)); Long now = System.currentTimeMillis(); @@ -212,8 +212,8 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { // first try to see if a record with this filename already exists... String[] projection = {FormsColumns._ID, FormsColumns.FORM_FILE_PATH}; - String[] selectionArgs = {filePath}; - String selection = FormsColumns.FORM_FILE_PATH + "=?"; + String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(filePath)}; + String selection = FormsColumns.FORM_FILE_PATH + " LIKE ?"; Cursor c = null; try { c = db.query(FORMS_TABLE_NAME, projection, selection, @@ -395,8 +395,8 @@ public int update(Uri uri, ContentValues values, String where, // updated // this probably isn't a great thing to do. if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String formFile = values - .getAsString(FormsColumns.FORM_FILE_PATH); + String formFile = DatabaseUtils.getAbsoluteFilePath(values + .getAsString(FormsColumns.FORM_FILE_PATH)); values.put(FormsColumns.MD5_HASH, FileUtils.getMd5Hash(new File(formFile))); } @@ -410,11 +410,11 @@ public int update(Uri uri, ContentValues values, String where, while (c.moveToNext()) { // before updating the paths, delete all the files if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String newFile = values - .getAsString(FormsColumns.FORM_FILE_PATH); - String delFile = c + String newFile = DatabaseUtils.getAbsoluteFilePath(values + .getAsString(FormsColumns.FORM_FILE_PATH)); + String delFile = DatabaseUtils.getAbsoluteFilePath(c .getString(c - .getColumnIndex(FormsColumns.FORM_FILE_PATH)); + .getColumnIndex(FormsColumns.FORM_FILE_PATH))); if (!newFile.equalsIgnoreCase(delFile)) { deleteFileOrDir(delFile); } @@ -464,10 +464,10 @@ public int update(Uri uri, ContentValues values, String where, } if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String formFile = values - .getAsString(FormsColumns.FORM_FILE_PATH); - String oldFile = update.getString(update - .getColumnIndex(FormsColumns.FORM_FILE_PATH)); + String formFile = DatabaseUtils.getAbsoluteFilePath(values + .getAsString(FormsColumns.FORM_FILE_PATH)); + String oldFile = DatabaseUtils.getAbsoluteFilePath(update.getString(update + .getColumnIndex(FormsColumns.FORM_FILE_PATH))); if (formFile == null || !formFile.equalsIgnoreCase(oldFile)) { deleteFileOrDir(oldFile); @@ -478,8 +478,7 @@ public int update(Uri uri, ContentValues values, String where, deleteFileOrDir(update .getString(update .getColumnIndex(FormsColumns.JRCACHE_FILE_PATH))); - String newMd5 = FileUtils - .getMd5Hash(new File(formFile)); + String newMd5 = FileUtils.getMd5Hash(new File(formFile)); values.put(FormsColumns.MD5_HASH, newMd5); values.put(FormsColumns.JRCACHE_FILE_PATH, DatabaseUtils.getRelativeFilePath(Collect.CACHE_PATH + File.separator + newMd5 + ".formdef")); diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java index 9abd0bcb3ac..02ce8c36109 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java @@ -25,6 +25,7 @@ import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.listeners.DiskSyncListener; import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; +import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.Validator; @@ -102,12 +103,11 @@ protected String doInBackground(Void... params) { while (cursor.moveToNext()) { // For each element in the provider, see if the file already exists - String sqlFilename = - cursor.getString( - cursor.getColumnIndex(FormsColumns.FORM_FILE_PATH)); + String formFilePath = DatabaseUtils.getAbsoluteFilePath(cursor.getString( + cursor.getColumnIndex(FormsColumns.FORM_FILE_PATH))); String md5 = cursor.getString( cursor.getColumnIndex(FormsColumns.MD5_HASH)); - File sqlFile = new File(sqlFilename); + File sqlFile = new File(formFilePath); if (sqlFile.exists()) { // remove it from the list of forms (we only want forms // we haven't added at the end) @@ -302,7 +302,7 @@ private ContentValues buildContentValues(File formDefFile) throws IllegalArgumen updateValues.put(FormsColumns.AUTO_SEND, fields.get(FileUtils.AUTO_SEND)); // Note, the path doesn't change here, but it needs to be included so the // update will automatically update the .md5 and the cache path. - updateValues.put(FormsColumns.FORM_FILE_PATH, formDefFile.getAbsolutePath()); + updateValues.put(FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(formDefFile.getAbsolutePath())); return updateValues; } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java index 32a981a983d..f821456d57f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java @@ -302,7 +302,7 @@ private UriResult findExistingOrCreateNewUri(File formFile, Map private Uri saveNewForm(Map formInfo, File formFile, String mediaPath) { final ContentValues v = new ContentValues(); - v.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, formFile.getAbsolutePath()); + v.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(formFile.getAbsolutePath())); v.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, DatabaseUtils.getRelativeFilePath(mediaPath)); v.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, formInfo.get(FileUtils.TITLE)); v.put(FormsProviderAPI.FormsColumns.JR_VERSION, formInfo.get(FileUtils.VERSION)); @@ -356,7 +356,7 @@ private FileResult downloadXform(String formName, String url) FileUtils.deleteAndReport(f); // set the file returned to the file we already had - String existingPath = c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH)); + String existingPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); f = new File(existingPath); Timber.w("Will use %s", existingPath); } From 84874bf02fb4868e204a6185f475a04233943867 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 21:31:06 +0100 Subject: [PATCH 09/12] Fixed bug in InstancesDao.deleteInstances() --- .../java/org/odk/collect/android/dao/InstancesDaoTest.java | 2 +- .../main/java/org/odk/collect/android/dao/InstancesDao.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java index b533e6959d8..4fe351942aa 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java @@ -174,7 +174,7 @@ public void deleteInstancesTest() { List absoluteInstanceFilePaths = new ArrayList<>(); absoluteInstanceFilePaths.add(Collect.INSTANCES_PATH + "/Hypertension Screening_2017-02-20_14-03-53/Hypertension Screening_2017-02-20_14-03-53.xml"); - absoluteInstanceFilePaths.add("/Biggest N of Set_2017-02-20_14-06-51/Biggest N of Set_2017-02-20_14-06-51.xml"); + absoluteInstanceFilePaths.add("/instances/Biggest N of Set_2017-02-20_14-06-51/Biggest N of Set_2017-02-20_14-06-51.xml"); instancesDao.deleteInstances(absoluteInstanceFilePaths); instances = DatabaseUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java index 79f86d18ea8..86a3d26e221 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java @@ -276,8 +276,8 @@ public void deleteInstances(List absoluteInstanceFilePaths) { selection.append(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); int j = 0; while (j < selectionArgs.length) { - selectionArgs[j] = "%" + absoluteInstanceFilePaths.get( - counter * ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER + j); + selectionArgs[j] = "%" + DatabaseUtils.getRelativeFilePath(absoluteInstanceFilePaths.get( + counter * ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER + j)); selection.append(" LIKE ?"); if (j != selectionArgs.length - 1) { From 4005afe35b9f98c1575bec73044a89bfd8005597 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 21:51:56 +0100 Subject: [PATCH 10/12] Added tests --- .../android/utilities/DatabaseUtilsTest.java | 36 +++++++++++++++++++ .../android/utilities/DatabaseUtils.java | 8 ++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java new file mode 100644 index 00000000000..a3c21a8a508 --- /dev/null +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java @@ -0,0 +1,36 @@ +package org.odk.collect.android.utilities; + +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class DatabaseUtilsTest { + + @Test + public void getAbsoluteFilePathTest() { + assertEquals("", DatabaseUtils.getAbsoluteFilePath(null)); + + assertEquals("/storage/emulated/0/odk/forms/selectext.xml", DatabaseUtils.getAbsoluteFilePath("/forms/selectext.xml")); + assertEquals("/storage/emulated/0/odk/forms/selectext.xml", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext.xml")); + + assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getAbsoluteFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + + assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", DatabaseUtils.getAbsoluteFilePath("/forms/selectext-media/itemsets.csv")); + assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); + } + + @Test + public void getRelativeFilePathTest() { + assertEquals("", DatabaseUtils.getRelativeFilePath(null)); + + assertEquals("/forms/selectext.xml", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext.xml")); + assertEquals("/forms/selectext.xml", DatabaseUtils.getRelativeFilePath("/forms/selectext.xml")); + + assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getRelativeFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + + assertEquals("/forms/selectext-media/itemsets.csv", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); + assertEquals("/forms/selectext-media/itemsets.csv", DatabaseUtils.getRelativeFilePath("/forms/selectext-media/itemsets.csv")); + } +} diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java index 13b57a3da3f..6f55bce6a00 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java @@ -18,11 +18,17 @@ public class DatabaseUtils { private DatabaseUtils() { } public static String getAbsoluteFilePath(String filePath) { + if (filePath == null) { + return ""; + } return filePath.startsWith(Collect.ODK_ROOT) ? filePath : Collect.ODK_ROOT + filePath; } public static String getRelativeFilePath(String filePath) { - return filePath.substring(Collect.ODK_ROOT.length()); + if (filePath == null) { + return ""; + } + return filePath.startsWith(Collect.ODK_ROOT) ? filePath.substring(Collect.ODK_ROOT.length()) : filePath; } /** From c36d1a21829a7bc847a39f98eec3e60f12e46eb7 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 22:10:56 +0100 Subject: [PATCH 11/12] Code refactoring --- .../odk/collect/android/dao/FormsDaoTest.java | 34 ++-- .../collect/android/dao/InstancesDaoTest.java | 38 ++-- .../helpers/FormsDatabaseHelperTest.java | 4 +- .../helpers/InstancesDatabaseHelperTest.java | 4 +- .../tasks/InstanceServerUploaderTaskTest.java | 4 +- .../android/utilities/DatabaseUtilsTest.java | 36 ---- .../android/utilities/FileUtilsTest.java | 37 ++++ .../utilities/InstanceUploaderUtilsTest.java | 3 +- .../android/activities/FormEntryActivity.java | 3 +- .../org/odk/collect/android/dao/FormsDao.java | 4 +- .../odk/collect/android/dao/InstancesDao.java | 6 +- .../dao/helpers/ContentResolverHelper.java | 4 +- .../android/dao/helpers/FormsDaoHelper.java | 81 ++++++++- .../dao/helpers/InstancesDaoHelper.java | 70 ++++++++ .../android/database/ItemsetDbAdapter.java | 14 +- .../android/provider/FormsProvider.java | 25 ++- .../android/provider/InstanceProvider.java | 6 +- .../collect/android/tasks/DiskSyncTask.java | 5 +- .../collect/android/tasks/FormLoaderTask.java | 3 +- .../InstanceGoogleSheetsUploaderTask.java | 4 +- .../android/tasks/InstanceSyncTask.java | 9 +- .../collect/android/tasks/SaveToDiskTask.java | 3 +- .../android/upload/AutoSendWorker.java | 7 +- .../upload/InstanceGoogleSheetsUploader.java | 4 +- .../android/upload/InstanceUploader.java | 4 +- .../android/utilities/DatabaseUtils.java | 169 ------------------ .../utilities/DownloadFormListUtils.java | 2 +- .../collect/android/utilities/FileUtils.java | 14 ++ .../android/utilities/FormDownloader.java | 8 +- 29 files changed, 299 insertions(+), 306 deletions(-) delete mode 100644 collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java create mode 100644 collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java delete mode 100644 collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java index 0e02e348fd2..f825c14a10a 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/FormsDaoTest.java @@ -25,9 +25,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.odk.collect.android.application.Collect; +import org.odk.collect.android.dao.helpers.FormsDaoHelper; import org.odk.collect.android.dto.Form; import org.odk.collect.android.provider.FormsProviderAPI; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.ResetUtility; import java.io.File; @@ -65,7 +65,7 @@ public void setUp() throws IOException { @Test public void getAllFormsCursorTest() { Cursor cursor = formsDao.getFormsCursor(); - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(0)); @@ -80,7 +80,7 @@ public void getAllFormsCursorTest() { @Test public void getFormsCursorForFormIdTest() { Cursor cursor = formsDao.getFormsCursorForFormId("Birds"); - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(2, forms.size()); assertEquals(birdsForm, forms.get(0)); @@ -89,7 +89,7 @@ public void getFormsCursorForFormIdTest() { @Test public void getFormsCursorTest() { Cursor cursor = formsDao.getFormsCursor(null, null, null, null); - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(0)); @@ -103,7 +103,7 @@ public void getFormsCursorTest() { String sortOrder = FormsProviderAPI.FormsColumns.DISPLAY_NAME + " COLLATE NOCASE DESC"; cursor = formsDao.getFormsCursor(null, null, null, sortOrder); - forms = DatabaseUtils.getFormsFromCursor(cursor); + forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(7, forms.size()); assertEquals(biggestNOfSetForm, forms.get(6)); @@ -118,7 +118,7 @@ public void getFormsCursorTest() { String[] selectionArgs = {"Miramare"}; cursor = formsDao.getFormsCursor(null, selection, selectionArgs, null); - forms = DatabaseUtils.getFormsFromCursor(cursor); + forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(miramareForm, forms.get(0)); @@ -127,7 +127,7 @@ public void getFormsCursorTest() { @Test public void getFormsCursorForFormFilePathTest() { Cursor cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Miramare.xml"); - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(miramareForm, forms.get(0)); @@ -136,7 +136,7 @@ public void getFormsCursorForFormFilePathTest() { @Test public void updateInstanceTest() { Cursor cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Widgets.xml"); - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(widgetsForm, forms.get(0)); @@ -153,10 +153,10 @@ public void updateInstanceTest() { String where = FormsProviderAPI.FormsColumns.DISPLAY_NAME + "=?"; String[] whereArgs = {"Widgets"}; - assertEquals(formsDao.updateForm(DatabaseUtils.getValuesFromFormObject(widgetsForm), where, whereArgs), 1); + assertEquals(formsDao.updateForm(FormsDaoHelper.getValuesFromFormObject(widgetsForm), where, whereArgs), 1); cursor = formsDao.getFormsCursorForFormFilePath(Collect.FORMS_PATH + "/Widgets.xml"); - forms = DatabaseUtils.getFormsFromCursor(cursor); + forms = FormsDaoHelper.getFormsFromCursor(cursor); assertEquals(1, forms.size()); assertEquals(widgetsForm, forms.get(0)); @@ -180,7 +180,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/ccce6015dd1b8f935f5f3058e81eeb43.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(biggestNOfSetForm)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(biggestNOfSetForm)); assertTrue(new File(Collect.FORMS_PATH + "/Birds.xml").createNewFile()); birdsForm = new Form.Builder() @@ -194,7 +194,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4cd980d50f884362afba842cbff3a798.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(birdsForm)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(birdsForm)); assertTrue(new File(Collect.FORMS_PATH + "/Miramare.xml").createNewFile()); miramareForm = new Form.Builder() @@ -207,7 +207,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/e733627cdbf220929bf9c4899cb983ea.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(miramareForm)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(miramareForm)); assertTrue(new File(Collect.FORMS_PATH + "/Geo Tagger v2.xml").createNewFile()); geoTaggerV2Form = new Form.Builder() @@ -220,7 +220,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/1d5e9109298c8ef02bc523b17d7c0451.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(geoTaggerV2Form)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(geoTaggerV2Form)); assertTrue(new File(Collect.FORMS_PATH + "/Widgets.xml").createNewFile()); widgetsForm = new Form.Builder() @@ -233,7 +233,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/0eacc6333449e66826326eb5fcc75749.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(widgetsForm)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(widgetsForm)); assertTrue(new File(Collect.FORMS_PATH + "/sample.xml").createNewFile()); sampleForm = new Form.Builder() @@ -246,7 +246,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4f495fddd1f2544f65444ea83d25f425.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(sampleForm)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(sampleForm)); assertTrue(new File(Collect.FORMS_PATH + "/Birds_4.xml").createNewFile()); birds2Form = new Form.Builder() @@ -260,7 +260,7 @@ private void setUpSampleForms() throws IOException { .jrCacheFilePath(Collect.ODK_ROOT + "/.cache/4cd980d50f884362afba842cbff3a775.formdef") .build(); - formsDao.saveForm(DatabaseUtils.getValuesFromFormObject(birds2Form)); + formsDao.saveForm(FormsDaoHelper.getValuesFromFormObject(birds2Form)); } @After diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java index 4fe351942aa..95f6bf1ef02 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/dao/InstancesDaoTest.java @@ -27,9 +27,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.odk.collect.android.application.Collect; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; -import org.odk.collect.android.utilities.DatabaseUtils; import java.util.ArrayList; import java.util.List; @@ -69,7 +69,7 @@ public void setUp() { @Test public void getUnsentInstancesCursorTest() { Cursor cursor = instancesDao.getUnsentInstancesCursor(); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(4, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -81,7 +81,7 @@ public void getUnsentInstancesCursorTest() { @Test public void getSentInstancesCursorTest() { Cursor cursor = instancesDao.getSentInstancesCursor(); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -91,7 +91,7 @@ public void getSentInstancesCursorTest() { @Test public void getSavedInstancesCursorTest() { Cursor cursor = instancesDao.getSavedInstancesCursor(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME + " ASC"); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(5, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -104,7 +104,7 @@ public void getSavedInstancesCursorTest() { @Test public void getFinalizedInstancesCursorTest() { Cursor cursor = instancesDao.getFinalizedInstancesCursor(); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -113,7 +113,7 @@ public void getFinalizedInstancesCursorTest() { @Test public void getInstancesCursorForFilePathTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Hypertension Screening_2017-02-20_14-03-53/Hypertension Screening_2017-02-20_14-03-53.xml"); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(hypertensionScreeningInstance, instances.get(0)); @@ -122,7 +122,7 @@ public void getInstancesCursorForFilePathTest() { @Test public void getAllCompletedUndeletedInstancesCursorTest() { Cursor cursor = instancesDao.getAllCompletedUndeletedInstancesCursor(); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(2, instances.size()); assertEquals(biggestNOfSetInstance, instances.get(0)); @@ -132,7 +132,7 @@ public void getAllCompletedUndeletedInstancesCursorTest() { @Test public void getInstancesCursorForIdTest() { Cursor cursor = instancesDao.getInstancesCursorForId("2"); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(cascadingSelectInstance, instances.get(0)); @@ -141,7 +141,7 @@ public void getInstancesCursorForIdTest() { @Test public void updateInstanceTest() { Cursor cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - List instances = DatabaseUtils.getInstancesFromCursor(cursor); + List instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -157,11 +157,11 @@ public void updateInstanceTest() { String where = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + "=?"; String[] whereArgs = {Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"}; - assertEquals(instancesDao.updateInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); + assertEquals(instancesDao.updateInstance(InstancesDaoHelper.getValuesFromInstanceObject(biggestNOfSet2Instance), where, whereArgs), 1); cursor = instancesDao.getInstancesCursorForFilePath(Collect.INSTANCES_PATH + "/Biggest N of Set_2017-02-20_14-24-46/Biggest N of Set_2017-02-20_14-24-46.xml"); - instances = DatabaseUtils.getInstancesFromCursor(cursor); + instances = InstancesDaoHelper.getInstancesFromCursor(cursor); assertEquals(1, instances.size()); assertEquals(biggestNOfSet2Instance, instances.get(0)); @@ -169,7 +169,7 @@ public void updateInstanceTest() { @Test public void deleteInstancesTest() { - List instances = DatabaseUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + List instances = InstancesDaoHelper.getInstancesFromCursor(instancesDao.getInstancesCursor()); assertEquals(6, instances.size()); List absoluteInstanceFilePaths = new ArrayList<>(); @@ -177,7 +177,7 @@ public void deleteInstancesTest() { absoluteInstanceFilePaths.add("/instances/Biggest N of Set_2017-02-20_14-06-51/Biggest N of Set_2017-02-20_14-06-51.xml"); instancesDao.deleteInstances(absoluteInstanceFilePaths); - instances = DatabaseUtils.getInstancesFromCursor(instancesDao.getInstancesCursor()); + instances = InstancesDaoHelper.getInstancesFromCursor(instancesDao.getInstancesCursor()); assertEquals(4, instances.size()); for (Instance instance : instances) { @@ -194,7 +194,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487595836793L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(hypertensionScreeningInstance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(hypertensionScreeningInstance)); cascadingSelectInstance = new Instance.Builder() .displayName("Cascading Select Form") @@ -203,7 +203,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596015000L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(cascadingSelectInstance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(cascadingSelectInstance)); biggestNOfSetInstance = new Instance.Builder() .displayName("Biggest N of Set") @@ -212,7 +212,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_SUBMITTED) .lastStatusChangeDate(1487596015100L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSetInstance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(biggestNOfSetInstance)); widgetsInstance = new Instance.Builder() .displayName("Widgets") @@ -222,7 +222,7 @@ private void fillDatabase() { .lastStatusChangeDate(1487596020803L) .deletedDate(1487596020803L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(widgetsInstance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(widgetsInstance)); sampleInstance = new Instance.Builder() .displayName("sample") @@ -231,7 +231,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_INCOMPLETE) .lastStatusChangeDate(1487596026373L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(sampleInstance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(sampleInstance)); biggestNOfSet2Instance = new Instance.Builder() .displayName("Biggest N of Set") @@ -240,7 +240,7 @@ private void fillDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(1487597090653L) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(biggestNOfSet2Instance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(biggestNOfSet2Instance)); } @After diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java index 339b21a6855..161af5882e4 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/FormsDatabaseHelperTest.java @@ -8,8 +8,8 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.odk.collect.android.dao.FormsDao; +import org.odk.collect.android.dao.helpers.FormsDaoHelper; import org.odk.collect.android.dto.Form; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.SQLiteUtils; @@ -81,7 +81,7 @@ public void testMigration() throws IOException { } private void assertThatFormsAreKeptAfterUpgrading() { - List forms = DatabaseUtils.getFormsFromCursor(new FormsDao().getFormsCursor()); + List forms = FormsDaoHelper.getFormsFromCursor(new FormsDao().getFormsCursor()); assertEquals(1, forms.size()); assertEquals("2019051302", forms.get(0).getJrVersion()); assertEquals("92ba8106dcb779943c1de163d73e1069", forms.get(0).getMD5Hash()); diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java index dd8c8588d92..0d91829869f 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/database/helpers/InstancesDatabaseHelperTest.java @@ -8,9 +8,9 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.utilities.FileUtils; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.SQLiteUtils; import java.io.File; @@ -70,7 +70,7 @@ public void testMigration() throws IOException { } private void assertThatInstancesAreKeptAfterMigrating() { - List instances = DatabaseUtils.getInstancesFromCursor(new InstancesDao().getInstancesCursor(null, null)); + List instances = InstancesDaoHelper.getInstancesFromCursor(new InstancesDao().getInstancesCursor(null, null)); assertEquals(2, instances.size()); assertEquals("complete", instances.get(0).getStatus()); assertEquals(Long.valueOf(1564413556249L), instances.get(0).getLastStatusChangeDate()); diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java index f3ec39b8f85..7f01cc2d15d 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/tasks/InstanceServerUploaderTaskTest.java @@ -9,10 +9,10 @@ import org.junit.Rule; import org.junit.Test; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.test.MockedServerTest; -import org.odk.collect.android.utilities.DatabaseUtils; import java.io.File; @@ -93,7 +93,7 @@ private long createStoredInstance() throws Exception { .lastStatusChangeDate(123L) .build(); - Uri contentUri = dao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(i)); + Uri contentUri = dao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(i)); return Long.parseLong(contentUri.toString().substring(InstanceProviderAPI.InstanceColumns.CONTENT_URI.toString().length() + 1)); } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java deleted file mode 100644 index a3c21a8a508..00000000000 --- a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/DatabaseUtilsTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.odk.collect.android.utilities; - -import org.junit.Test; - -import static junit.framework.TestCase.assertEquals; - -public class DatabaseUtilsTest { - - @Test - public void getAbsoluteFilePathTest() { - assertEquals("", DatabaseUtils.getAbsoluteFilePath(null)); - - assertEquals("/storage/emulated/0/odk/forms/selectext.xml", DatabaseUtils.getAbsoluteFilePath("/forms/selectext.xml")); - assertEquals("/storage/emulated/0/odk/forms/selectext.xml", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext.xml")); - - assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getAbsoluteFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); - assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); - - assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", DatabaseUtils.getAbsoluteFilePath("/forms/selectext-media/itemsets.csv")); - assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", DatabaseUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); - } - - @Test - public void getRelativeFilePathTest() { - assertEquals("", DatabaseUtils.getRelativeFilePath(null)); - - assertEquals("/forms/selectext.xml", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext.xml")); - assertEquals("/forms/selectext.xml", DatabaseUtils.getRelativeFilePath("/forms/selectext.xml")); - - assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); - assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", DatabaseUtils.getRelativeFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); - - assertEquals("/forms/selectext-media/itemsets.csv", DatabaseUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); - assertEquals("/forms/selectext-media/itemsets.csv", DatabaseUtils.getRelativeFilePath("/forms/selectext-media/itemsets.csv")); - } -} diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java new file mode 100644 index 00000000000..981a0c90155 --- /dev/null +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java @@ -0,0 +1,37 @@ +package org.odk.collect.android.utilities; + +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNull; + +public class FileUtilsTest { + + @Test + public void getAbsoluteFilePathTest() { + assertNull(FileUtils.getAbsoluteFilePath(null)); + + assertEquals("/storage/emulated/0/odk/forms/selectext.xml", FileUtils.getAbsoluteFilePath("/forms/selectext.xml")); + assertEquals("/storage/emulated/0/odk/forms/selectext.xml", FileUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext.xml")); + + assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", FileUtils.getAbsoluteFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + assertEquals("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", FileUtils.getAbsoluteFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + + assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", FileUtils.getAbsoluteFilePath("/forms/selectext-media/itemsets.csv")); + assertEquals("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv", FileUtils.getAbsoluteFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); + } + + @Test + public void getRelativeFilePathTest() { + assertNull(FileUtils.getRelativeFilePath(null)); + + assertEquals("/forms/selectext.xml", FileUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext.xml")); + assertEquals("/forms/selectext.xml", FileUtils.getRelativeFilePath("/forms/selectext.xml")); + + assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", FileUtils.getRelativeFilePath("/storage/emulated/0/odk/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + assertEquals("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml", FileUtils.getRelativeFilePath("/instances/All widgets_2019-11-13_14-00-22/All widgets_2019-11-13_14-00-22.xml")); + + assertEquals("/forms/selectext-media/itemsets.csv", FileUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); + assertEquals("/forms/selectext-media/itemsets.csv", FileUtils.getRelativeFilePath("/forms/selectext-media/itemsets.csv")); + } +} diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java index 42b8336794d..984cf468442 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/InstanceUploaderUtilsTest.java @@ -11,6 +11,7 @@ import org.junit.runner.RunWith; import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; @@ -60,7 +61,7 @@ private void fillTestDatabase() { .status(InstanceProviderAPI.STATUS_COMPLETE) .lastStatusChangeDate(time) .build(); - instancesDao.saveInstance(DatabaseUtils.getValuesFromInstanceObject(instance)); + instancesDao.saveInstance(InstancesDaoHelper.getValuesFromInstanceObject(instance)); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java b/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java index 3f5ce2e69a2..fafe68e103c 100644 --- a/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java +++ b/collect_app/src/main/java/org/odk/collect/android/activities/FormEntryActivity.java @@ -134,7 +134,6 @@ import org.odk.collect.android.tasks.SaveToDiskTask; import org.odk.collect.android.upload.AutoSendWorker; import org.odk.collect.android.utilities.ApplicationConstants; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.DestroyableLifecyleOwner; import org.odk.collect.android.utilities.DialogUtils; import org.odk.collect.android.utilities.FileUtils; @@ -2016,7 +2015,7 @@ public void onClick(DialogInterface dialog, ContentValues values = new ContentValues(); values.put(FormsColumns.LANGUAGE, languages[whichButton]); String selection = FormsColumns.FORM_FILE_PATH + " LIKE ?"; - String[] selectArgs = {"%" + DatabaseUtils.getRelativeFilePath(formPath)}; + String[] selectArgs = {"%" + FileUtils.getRelativeFilePath(formPath)}; int updated = new FormsDao().updateForm(values, selection, selectArgs); Timber.i("Updated language to: %s in %d rows", languages[whichButton], diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java index b1cb8afb0f5..80608296f9b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/FormsDao.java @@ -23,7 +23,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.provider.FormsProviderAPI; -import org.odk.collect.android.utilities.DatabaseUtils; +import org.odk.collect.android.utilities.FileUtils; import java.util.ArrayList; import java.util.List; @@ -165,7 +165,7 @@ public String getFormMediaPath(String formId, String formVersion) { public Cursor getFormsCursorForFormFilePath(String formFilePath) { String selection = FormsProviderAPI.FormsColumns.FORM_FILE_PATH + " LIKE ?"; - String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(formFilePath)}; + String[] selectionArgs = {"%" + FileUtils.getRelativeFilePath(formFilePath)}; return getFormsCursor(null, selection, selectionArgs, null); } diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java index 86a3d26e221..cc678d71bc4 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/InstancesDao.java @@ -24,7 +24,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; -import org.odk.collect.android.utilities.DatabaseUtils; +import org.odk.collect.android.utilities.FileUtils; import java.util.List; @@ -164,7 +164,7 @@ public CursorLoader getFinalizedInstancesCursorLoader(CharSequence charSequence, public Cursor getInstancesCursorForFilePath(String path) { String selection = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; - String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; + String[] selectionArgs = {"%" + FileUtils.getRelativeFilePath(path)}; return getInstancesCursor(null, selection, selectionArgs, null); } @@ -276,7 +276,7 @@ public void deleteInstances(List absoluteInstanceFilePaths) { selection.append(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); int j = 0; while (j < selectionArgs.length) { - selectionArgs[j] = "%" + DatabaseUtils.getRelativeFilePath(absoluteInstanceFilePaths.get( + selectionArgs[j] = "%" + FileUtils.getRelativeFilePath(absoluteInstanceFilePaths.get( counter * ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER + j)); selection.append(" LIKE ?"); diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java index f5e37f99297..596451067b0 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/ContentResolverHelper.java @@ -25,7 +25,7 @@ import org.odk.collect.android.logic.FormInfo; import org.odk.collect.android.provider.FormsProviderAPI; import org.odk.collect.android.provider.InstanceProviderAPI; -import org.odk.collect.android.utilities.DatabaseUtils; +import org.odk.collect.android.utilities.FileUtils; public final class ContentResolverHelper { @@ -68,7 +68,7 @@ public static String getFormPath(Uri uri) { try (Cursor c = getContentResolver().query(uri, null, null, null, null)) { if (c != null && c.getCount() == 1) { c.moveToFirst(); - formPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); + formPath = FileUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); } } return formPath; diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java index 1721a165b8c..28ca35ca370 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/FormsDaoHelper.java @@ -14,11 +14,17 @@ package org.odk.collect.android.dao.helpers; +import android.content.ContentValues; import android.database.Cursor; +import android.provider.BaseColumns; import org.odk.collect.android.dao.FormsDao; +import org.odk.collect.android.dto.Form; import org.odk.collect.android.provider.FormsProviderAPI; -import org.odk.collect.android.utilities.DatabaseUtils; +import org.odk.collect.android.utilities.FileUtils; + +import java.util.ArrayList; +import java.util.List; public final class FormsDaoHelper { @@ -42,7 +48,7 @@ public static String getAbsoluteFormPath(String selection, String[] selectionArg try (Cursor c = formsDao.getFormsCursor(selection, selectionArgs)) { if (c != null && c.getCount() > 0) { c.moveToFirst(); - formPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); + formPath = FileUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); } } return formPath; @@ -58,4 +64,75 @@ public static String getFormLanguage(String formPath) { } return newLanguage; } + + /** + * Returns all forms available through the cursor and closes the cursor. + */ + public static List getFormsFromCursor(Cursor cursor) { + List forms = new ArrayList<>(); + if (cursor != null) { + try { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + int idColumnIndex = cursor.getColumnIndex(BaseColumns._ID); + int displayNameColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DISPLAY_NAME); + int descriptionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DESCRIPTION); + int jrFormIdColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_FORM_ID); + int jrVersionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_VERSION); + int formFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH); + int submissionUriColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.SUBMISSION_URI); + int base64RSAPublicKeyColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY); + int md5HashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.MD5_HASH); + int dateColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DATE); + int jrCacheFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH); + int formMediaPathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH); + int languageColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LANGUAGE); + int autoSendColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_SEND); + int autoDeleteColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_DELETE); + int lastDetectedFormVersionHashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LAST_DETECTED_FORM_VERSION_HASH); + + Form form = new Form.Builder() + .id(cursor.getInt(idColumnIndex)) + .displayName(cursor.getString(displayNameColumnIndex)) + .description(cursor.getString(descriptionColumnIndex)) + .jrFormId(cursor.getString(jrFormIdColumnIndex)) + .jrVersion(cursor.getString(jrVersionColumnIndex)) + .formFilePath(cursor.getString(formFilePathColumnIndex)) + .submissionUri(cursor.getString(submissionUriColumnIndex)) + .base64RSAPublicKey(cursor.getString(base64RSAPublicKeyColumnIndex)) + .md5Hash(cursor.getString(md5HashColumnIndex)) + .date(cursor.getLong(dateColumnIndex)) + .jrCacheFilePath(cursor.getString(jrCacheFilePathColumnIndex)) + .formMediaPath(cursor.getString(formMediaPathColumnIndex)) + .language(cursor.getString(languageColumnIndex)) + .autoSend(cursor.getString(autoSendColumnIndex)) + .autoDelete(cursor.getString(autoDeleteColumnIndex)) + .lastDetectedFormVersionHash(cursor.getString(lastDetectedFormVersionHashColumnIndex)) + .build(); + + forms.add(form); + } + } finally { + cursor.close(); + } + } + return forms; + } + + public static ContentValues getValuesFromFormObject(Form form) { + ContentValues values = new ContentValues(); + values.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, form.getDisplayName()); + values.put(FormsProviderAPI.FormsColumns.DESCRIPTION, form.getDescription()); + values.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, form.getJrFormId()); + values.put(FormsProviderAPI.FormsColumns.JR_VERSION, form.getJrVersion()); + values.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, form.getFormFilePath()); + values.put(FormsProviderAPI.FormsColumns.SUBMISSION_URI, form.getSubmissionUri()); + values.put(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY, form.getBASE64RSAPublicKey()); + values.put(FormsProviderAPI.FormsColumns.MD5_HASH, form.getMD5Hash()); + values.put(FormsProviderAPI.FormsColumns.DATE, form.getDate()); + values.put(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH, form.getJrCacheFilePath()); + values.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, form.getFormMediaPath()); + values.put(FormsProviderAPI.FormsColumns.LANGUAGE, form.getLanguage()); + return values; + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/InstancesDaoHelper.java b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/InstancesDaoHelper.java index 04d3e8e54c7..20d57592b5b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dao/helpers/InstancesDaoHelper.java +++ b/collect_app/src/main/java/org/odk/collect/android/dao/helpers/InstancesDaoHelper.java @@ -14,16 +14,21 @@ package org.odk.collect.android.dao.helpers; +import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dto.Instance; import org.odk.collect.android.logic.FormController; import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.preferences.GeneralKeys; import org.odk.collect.android.provider.InstanceProviderAPI; +import java.util.ArrayList; +import java.util.List; + import timber.log.Timber; public final class InstancesDaoHelper { @@ -92,4 +97,69 @@ public static boolean isInstanceAvailable(String path) { } return isAvailable; } + + /** + * Returns all instances available through the cursor and closes the cursor. + */ + public static List getInstancesFromCursor(Cursor cursor) { + List instances = new ArrayList<>(); + if (cursor != null) { + try { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + int displayNameColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME); + int submissionUriColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI); + int canEditWhenCompleteIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE); + int instanceFilePathIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); + int jrFormIdColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_FORM_ID); + int jrVersionColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_VERSION); + int statusColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS); + int lastStatusChangeDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE); + int deletedDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DELETED_DATE); + + int databaseIdIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns._ID); + + Instance instance = new Instance.Builder() + .displayName(cursor.getString(displayNameColumnIndex)) + .submissionUri(cursor.getString(submissionUriColumnIndex)) + .canEditWhenComplete(cursor.getString(canEditWhenCompleteIndex)) + .instanceFilePath(cursor.getString(instanceFilePathIndex)) + .jrFormId(cursor.getString(jrFormIdColumnIndex)) + .jrVersion(cursor.getString(jrVersionColumnIndex)) + .status(cursor.getString(statusColumnIndex)) + .lastStatusChangeDate(cursor.getLong(lastStatusChangeDateColumnIndex)) + .deletedDate(cursor.getLong(deletedDateColumnIndex)) + .databaseId(cursor.getLong(databaseIdIndex)) + .build(); + + instances.add(instance); + } + } finally { + cursor.close(); + } + } + return instances; + } + + /** + * Returns the values of an instance as a ContentValues object for use with + * {@link org.odk.collect.android.dao.InstancesDao#saveInstance(ContentValues)} (ContentValues)} + * or {@link org.odk.collect.android.dao.InstancesDao#updateInstance(ContentValues, String, String[])} + * + * Does NOT include the database ID. + */ + public static ContentValues getValuesFromInstanceObject(Instance instance) { + ContentValues values = new ContentValues(); + values.put(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME, instance.getDisplayName()); + values.put(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI, instance.getSubmissionUri()); + values.put(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE, instance.getCanEditWhenComplete()); + values.put(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH, instance.getInstanceFilePath()); + values.put(InstanceProviderAPI.InstanceColumns.JR_FORM_ID, instance.getJrFormId()); + values.put(InstanceProviderAPI.InstanceColumns.JR_VERSION, instance.getJrVersion()); + values.put(InstanceProviderAPI.InstanceColumns.STATUS, instance.getStatus()); + values.put(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE, instance.getLastStatusChangeDate()); + values.put(InstanceProviderAPI.InstanceColumns.DELETED_DATE, instance.getDeletedDate()); + + return values; + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java b/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java index 72c652cff6f..fc80dcd1b7b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java +++ b/collect_app/src/main/java/org/odk/collect/android/database/ItemsetDbAdapter.java @@ -7,7 +7,6 @@ import android.database.sqlite.SQLiteOpenHelper; import org.odk.collect.android.application.Collect; -import org.odk.collect.android.utilities.DatabaseUtils; import java.math.BigInteger; import java.security.MessageDigest; @@ -15,6 +14,9 @@ import timber.log.Timber; +import static org.odk.collect.android.utilities.FileUtils.getAbsoluteFilePath; +import static org.odk.collect.android.utilities.FileUtils.getRelativeFilePath; + public class ItemsetDbAdapter { private DatabaseHelper dbHelper; @@ -116,7 +118,7 @@ public boolean createTable(String formHash, String pathHash, String[] columns, S ContentValues cv = new ContentValues(); cv.put(KEY_ITEMSET_HASH, formHash); - cv.put(KEY_PATH, DatabaseUtils.getRelativeFilePath(path)); + cv.put(KEY_PATH, getRelativeFilePath(path)); db.insert(ITEMSET_TABLE, null, cv); return true; @@ -155,13 +157,13 @@ public void dropTable(String pathHash, String path) { // and remove the entry from the itemsets table String where = KEY_PATH + " LIKE ?"; - String[] whereArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; + String[] whereArgs = {"%" + getRelativeFilePath(path)}; db.delete(ITEMSET_TABLE, where, whereArgs); } public Cursor getItemsets(String path) { String selection = KEY_PATH + " LIKE ?"; - String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; + String[] selectionArgs = {"%" + getRelativeFilePath(path)}; return db.query(ITEMSET_TABLE, null, selection, selectionArgs, null, null, null); } @@ -170,14 +172,14 @@ public void delete(String path) { if (c != null) { if (c.getCount() == 1) { c.moveToFirst(); - String table = getMd5FromString(DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(KEY_PATH)))); + String table = getMd5FromString(getAbsoluteFilePath(c.getString(c.getColumnIndex(KEY_PATH)))); db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE + table); } c.close(); } String where = KEY_PATH + " LIKE ?"; - String[] whereArgs = {"%" + DatabaseUtils.getRelativeFilePath(path)}; + String[] whereArgs = {"%" + getRelativeFilePath(path)}; db.delete(ITEMSET_TABLE, where, whereArgs); } diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java index ab0b5a0670e..b878acdb382 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/FormsProvider.java @@ -31,7 +31,6 @@ import org.odk.collect.android.database.ItemsetDbAdapter; import org.odk.collect.android.database.helpers.FormsDatabaseHelper; import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.MediaUtils; @@ -177,10 +176,10 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { // Normalize the file path. // (don't trust the requester). - String filePath = DatabaseUtils.getAbsoluteFilePath(values.getAsString(FormsColumns.FORM_FILE_PATH)); + String filePath = FileUtils.getAbsoluteFilePath(values.getAsString(FormsColumns.FORM_FILE_PATH)); File form = new File(filePath); filePath = form.getAbsolutePath(); // normalized - values.put(FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(filePath)); + values.put(FormsColumns.FORM_FILE_PATH, FileUtils.getRelativeFilePath(filePath)); Long now = System.currentTimeMillis(); @@ -202,17 +201,17 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { if (!values.containsKey(FormsColumns.JRCACHE_FILE_PATH)) { String cachePath = Collect.CACHE_PATH + File.separator + md5 + ".formdef"; - values.put(FormsColumns.JRCACHE_FILE_PATH, DatabaseUtils.getRelativeFilePath(cachePath)); + values.put(FormsColumns.JRCACHE_FILE_PATH, FileUtils.getRelativeFilePath(cachePath)); } if (!values.containsKey(FormsColumns.FORM_MEDIA_PATH)) { - values.put(FormsColumns.FORM_MEDIA_PATH, DatabaseUtils.getRelativeFilePath(FileUtils.constructMediaPath(filePath))); + values.put(FormsColumns.FORM_MEDIA_PATH, FileUtils.getRelativeFilePath(FileUtils.constructMediaPath(filePath))); } SQLiteDatabase db = formsDatabaseHelper.getWritableDatabase(); // first try to see if a record with this filename already exists... String[] projection = {FormsColumns._ID, FormsColumns.FORM_FILE_PATH}; - String[] selectionArgs = {"%" + DatabaseUtils.getRelativeFilePath(filePath)}; + String[] selectionArgs = {"%" + FileUtils.getRelativeFilePath(filePath)}; String selection = FormsColumns.FORM_FILE_PATH + " LIKE ?"; Cursor c = null; try { @@ -244,7 +243,7 @@ public synchronized Uri insert(@NonNull Uri uri, ContentValues initialValues) { } private void deleteFileOrDir(String fileName) { - File file = new File(DatabaseUtils.getAbsoluteFilePath(fileName)); + File file = new File(FileUtils.getAbsoluteFilePath(fileName)); if (file.exists()) { if (file.isDirectory()) { // delete any media entries for files in this directory... @@ -395,7 +394,7 @@ public int update(Uri uri, ContentValues values, String where, // updated // this probably isn't a great thing to do. if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String formFile = DatabaseUtils.getAbsoluteFilePath(values + String formFile = FileUtils.getAbsoluteFilePath(values .getAsString(FormsColumns.FORM_FILE_PATH)); values.put(FormsColumns.MD5_HASH, FileUtils.getMd5Hash(new File(formFile))); @@ -410,9 +409,9 @@ public int update(Uri uri, ContentValues values, String where, while (c.moveToNext()) { // before updating the paths, delete all the files if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String newFile = DatabaseUtils.getAbsoluteFilePath(values + String newFile = FileUtils.getAbsoluteFilePath(values .getAsString(FormsColumns.FORM_FILE_PATH)); - String delFile = DatabaseUtils.getAbsoluteFilePath(c + String delFile = FileUtils.getAbsoluteFilePath(c .getString(c .getColumnIndex(FormsColumns.FORM_FILE_PATH))); if (!newFile.equalsIgnoreCase(delFile)) { @@ -464,9 +463,9 @@ public int update(Uri uri, ContentValues values, String where, } if (values.containsKey(FormsColumns.FORM_FILE_PATH)) { - String formFile = DatabaseUtils.getAbsoluteFilePath(values + String formFile = FileUtils.getAbsoluteFilePath(values .getAsString(FormsColumns.FORM_FILE_PATH)); - String oldFile = DatabaseUtils.getAbsoluteFilePath(update.getString(update + String oldFile = FileUtils.getAbsoluteFilePath(update.getString(update .getColumnIndex(FormsColumns.FORM_FILE_PATH))); if (formFile == null || !formFile.equalsIgnoreCase(oldFile)) { @@ -481,7 +480,7 @@ public int update(Uri uri, ContentValues values, String where, String newMd5 = FileUtils.getMd5Hash(new File(formFile)); values.put(FormsColumns.MD5_HASH, newMd5); values.put(FormsColumns.JRCACHE_FILE_PATH, - DatabaseUtils.getRelativeFilePath(Collect.CACHE_PATH + File.separator + newMd5 + ".formdef")); + FileUtils.getRelativeFilePath(Collect.CACHE_PATH + File.separator + newMd5 + ".formdef")); } count = db.update( diff --git a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java index 28cedc816d3..88b246fefb8 100644 --- a/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java +++ b/collect_app/src/main/java/org/odk/collect/android/provider/InstanceProvider.java @@ -32,7 +32,7 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.database.helpers.InstancesDatabaseHelper; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; -import org.odk.collect.android.utilities.DatabaseUtils; +import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.MediaUtils; import java.io.File; @@ -260,7 +260,7 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { if (del != null && del.getCount() > 0) { del.moveToFirst(); do { - String instanceFile = DatabaseUtils.getAbsoluteFilePath(del.getString( + String instanceFile = FileUtils.getAbsoluteFilePath(del.getString( del.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); @@ -285,7 +285,7 @@ public int delete(@NonNull Uri uri, String where, String[] whereArgs) { c.moveToFirst(); status = c.getString(c.getColumnIndex(InstanceColumns.STATUS)); do { - String instanceFile = DatabaseUtils.getAbsoluteFilePath(c.getString( + String instanceFile = FileUtils.getAbsoluteFilePath(c.getString( c.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); File instanceDir = (new File(instanceFile)).getParentFile(); deleteAllFilesInDirectory(instanceDir); diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java index 02ce8c36109..b64f7f782aa 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/DiskSyncTask.java @@ -25,7 +25,6 @@ import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.listeners.DiskSyncListener; import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.Validator; @@ -103,7 +102,7 @@ protected String doInBackground(Void... params) { while (cursor.moveToNext()) { // For each element in the provider, see if the file already exists - String formFilePath = DatabaseUtils.getAbsoluteFilePath(cursor.getString( + String formFilePath = FileUtils.getAbsoluteFilePath(cursor.getString( cursor.getColumnIndex(FormsColumns.FORM_FILE_PATH))); String md5 = cursor.getString( cursor.getColumnIndex(FormsColumns.MD5_HASH)); @@ -302,7 +301,7 @@ private ContentValues buildContentValues(File formDefFile) throws IllegalArgumen updateValues.put(FormsColumns.AUTO_SEND, fields.get(FileUtils.AUTO_SEND)); // Note, the path doesn't change here, but it needs to be included so the // update will automatically update the .md5 and the cache path. - updateValues.put(FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(formDefFile.getAbsolutePath())); + updateValues.put(FormsColumns.FORM_FILE_PATH, FileUtils.getRelativeFilePath(formDefFile.getAbsolutePath())); return updateValues; } diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java index 8e99a7e4fd7..dd2aab644a2 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java @@ -46,7 +46,6 @@ import org.odk.collect.android.logic.FormController; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.FormDefCache; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.ZipUtils; import java.io.File; @@ -106,7 +105,7 @@ protected void free() { FECWrapper data; public FormLoaderTask(String instancePath, String xpath, String waitingXPath) { - this.instancePath = DatabaseUtils.getAbsoluteFilePath(instancePath); + this.instancePath = FileUtils.getAbsoluteFilePath(instancePath); this.xpath = xpath; this.waitingXPath = waitingXPath; } diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java index 1cdeaea4444..cb47459c73d 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceGoogleSheetsUploaderTask.java @@ -19,11 +19,11 @@ import org.odk.collect.android.R; import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.FormsDao; +import org.odk.collect.android.dao.helpers.FormsDaoHelper; import org.odk.collect.android.dto.Form; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.upload.InstanceGoogleSheetsUploader; import org.odk.collect.android.upload.UploadException; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.InstanceUploaderUtils; import org.odk.collect.android.utilities.gdrive.GoogleAccountsManager; @@ -61,7 +61,7 @@ protected Outcome doInBackground(Long... instanceIdsToUpload) { // Get corresponding blank form and verify there is exactly 1 Cursor formCursor = new FormsDao().getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); - List forms = DatabaseUtils.getFormsFromCursor(formCursor); + List forms = FormsDaoHelper.getFormsFromCursor(formCursor); if (forms.size() != 1) { outcome.messagesByInstanceId.put(instance.getDatabaseId().toString(), diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java index edb17b2b29c..69fd5e624ba 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/InstanceSyncTask.java @@ -33,7 +33,6 @@ import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.EncryptionUtils; -import org.odk.collect.android.utilities.DatabaseUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -52,6 +51,8 @@ import timber.log.Timber; import static org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; +import static org.odk.collect.android.utilities.FileUtils.getRelativeFilePath; +import static org.odk.collect.android.utilities.FileUtils.getAbsoluteFilePath; /** * Background task for syncing form instances from the instances folder to the instances table. @@ -122,7 +123,7 @@ protected String doInBackground(Void... params) { instanceCursor.moveToPosition(-1); while (instanceCursor.moveToNext()) { - String instanceFilename = DatabaseUtils.getAbsoluteFilePath(instanceCursor.getString( + String instanceFilename = getAbsoluteFilePath(instanceCursor.getString( instanceCursor.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH))); String instanceStatus = instanceCursor.getString( instanceCursor.getColumnIndex(InstanceColumns.STATUS)); @@ -170,7 +171,7 @@ protected String doInBackground(Void... params) { // add missing fields into content values ContentValues values = new ContentValues(); - values.put(InstanceColumns.INSTANCE_FILE_PATH, DatabaseUtils.getRelativeFilePath(candidateInstance)); + values.put(InstanceColumns.INSTANCE_FILE_PATH, getRelativeFilePath(candidateInstance)); values.put(InstanceColumns.SUBMISSION_URI, submissionUri); values.put(InstanceColumns.DISPLAY_NAME, formName); values.put(InstanceColumns.JR_FORM_ID, jrFormId); @@ -263,7 +264,7 @@ private void encryptInstance(Cursor instanceCursor, String candidateInstance, EncryptionUtils.generateEncryptedSubmission(instanceXml, submissionXml, formInfo); values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE, Boolean.toString(false)); - instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?", new String[]{"%" + DatabaseUtils.getRelativeFilePath(candidateInstance)}); + instancesDao.updateInstance(values, InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?", new String[]{"%" + getRelativeFilePath(candidateInstance)}); SaveToDiskTask.manageFilesAfterSavingEncryptedForm(instanceXml, submissionXml); if (!EncryptionUtils.deletePlaintextFiles(instanceXml, null)) { diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java index 9849f425870..20fc0a1cdd4 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/SaveToDiskTask.java @@ -33,7 +33,6 @@ import org.odk.collect.android.utilities.EncryptionUtils; import org.odk.collect.android.utilities.EncryptionUtils.EncryptedFormInformation; import org.odk.collect.android.utilities.FileUtils; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.MediaManager; import java.io.File; @@ -180,7 +179,7 @@ private void updateInstanceDatabase(boolean incomplete, boolean canEditAfterComp // However, it could be a not-first time saving if the user has been using the manual // 'save data' option from the menu. So try to update first, then make a new one if that // fails. - String relativeInstancePath = DatabaseUtils.getRelativeFilePath(formController.getAbsoluteInstancePath()); + String relativeInstancePath = FileUtils.getRelativeFilePath(formController.getAbsoluteInstancePath()); String where = InstanceColumns.INSTANCE_FILE_PATH + " LIKE ?"; String[] whereArgs = {"%" + relativeInstancePath}; int updated = new InstancesDao().updateInstance(values, where, whereArgs); diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java index 5c3819c50ac..df35e2d0f48 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/AutoSendWorker.java @@ -33,6 +33,8 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dao.helpers.FormsDaoHelper; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Form; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.http.openrosa.OpenRosaHttpInterface; @@ -41,7 +43,6 @@ import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.provider.InstanceProviderAPI.InstanceColumns; import org.odk.collect.android.utilities.InstanceUploaderUtils; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.NotificationUtils; import org.odk.collect.android.utilities.PermissionUtils; import org.odk.collect.android.utilities.WebCredentialsUtils; @@ -201,7 +202,7 @@ private boolean networkTypeMatchesAutoSendSetting(NetworkInfo currentNetworkInfo @NonNull private List getInstancesToAutoSend(boolean isAutoSendAppSettingEnabled) { Cursor c = new InstancesDao().getFinalizedInstancesCursor(); - List allFinalized = DatabaseUtils.getInstancesFromCursor(c); + List allFinalized = InstancesDaoHelper.getInstancesFromCursor(c); List toUpload = new ArrayList<>(); for (Instance instance : allFinalized) { @@ -246,7 +247,7 @@ public static boolean formShouldBeAutoSent(String jrFormId, boolean isAutoSendAp */ private boolean atLeastOneFormSpecifiesAutoSend() { try (Cursor cursor = new FormsDao().getFormsCursor()) { - List forms = DatabaseUtils.getFormsFromCursor(cursor); + List forms = FormsDaoHelper.getFormsFromCursor(cursor); for (Form form : forms) { if (Boolean.valueOf(form.getAutoSend())) { return true; diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java index 9437edaf15a..0c9b962e716 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceGoogleSheetsUploader.java @@ -34,6 +34,7 @@ import org.odk.collect.android.R; import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.FormsDao; +import org.odk.collect.android.dao.helpers.FormsDaoHelper; import org.odk.collect.android.dto.Form; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.exception.BadUrlException; @@ -41,7 +42,6 @@ import org.odk.collect.android.preferences.GeneralKeys; import org.odk.collect.android.preferences.GeneralSharedPreferences; import org.odk.collect.android.tasks.FormLoaderTask; -import org.odk.collect.android.utilities.DatabaseUtils; import org.odk.collect.android.utilities.FileUtils; import org.odk.collect.android.utilities.TextUtils; import org.odk.collect.android.utilities.UrlUtils; @@ -97,7 +97,7 @@ public String uploadOneSubmission(Instance instance, String spreadsheetUrl) thro // Get corresponding blank form and verify there is exactly 1 Cursor formCursor = new FormsDao().getFormsCursor(instance.getJrFormId(), instance.getJrVersion()); - List forms = DatabaseUtils.getFormsFromCursor(formCursor); + List forms = FormsDaoHelper.getFormsFromCursor(formCursor); try { if (forms.size() != 1) { diff --git a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java index b220014d0a3..178d2fe4580 100644 --- a/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java +++ b/collect_app/src/main/java/org/odk/collect/android/upload/InstanceUploader.java @@ -23,10 +23,10 @@ import org.odk.collect.android.application.Collect; import org.odk.collect.android.dao.FormsDao; import org.odk.collect.android.dao.InstancesDao; +import org.odk.collect.android.dao.helpers.InstancesDaoHelper; import org.odk.collect.android.dto.Instance; import org.odk.collect.android.provider.InstanceProviderAPI; import org.odk.collect.android.utilities.ApplicationConstants; -import org.odk.collect.android.utilities.DatabaseUtils; import java.util.ArrayList; import java.util.List; @@ -77,7 +77,7 @@ public List getInstancesFromIds(Long... instanceDatabaseIds) { String selection = selectionBuf.toString(); Cursor c = new InstancesDao().getInstancesCursor(selection, selectionArgs); - instancesToUpload.addAll(DatabaseUtils.getInstancesFromCursor(c)); + instancesToUpload.addAll(InstancesDaoHelper.getInstancesFromCursor(c)); counter++; } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java deleted file mode 100644 index 6f55bce6a00..00000000000 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DatabaseUtils.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.odk.collect.android.utilities; - -import android.content.ContentValues; -import android.database.Cursor; -import android.provider.BaseColumns; - -import org.odk.collect.android.application.Collect; -import org.odk.collect.android.dto.Form; -import org.odk.collect.android.dto.Instance; -import org.odk.collect.android.provider.FormsProviderAPI; -import org.odk.collect.android.provider.InstanceProviderAPI; - -import java.util.ArrayList; -import java.util.List; - -public class DatabaseUtils { - - private DatabaseUtils() { } - - public static String getAbsoluteFilePath(String filePath) { - if (filePath == null) { - return ""; - } - return filePath.startsWith(Collect.ODK_ROOT) ? filePath : Collect.ODK_ROOT + filePath; - } - - public static String getRelativeFilePath(String filePath) { - if (filePath == null) { - return ""; - } - return filePath.startsWith(Collect.ODK_ROOT) ? filePath.substring(Collect.ODK_ROOT.length()) : filePath; - } - - /** - * Returns all instances available through the cursor and closes the cursor. - */ - public static List getInstancesFromCursor(Cursor cursor) { - List instances = new ArrayList<>(); - if (cursor != null) { - try { - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - int displayNameColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME); - int submissionUriColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI); - int canEditWhenCompleteIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE); - int instanceFilePathIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH); - int jrFormIdColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_FORM_ID); - int jrVersionColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_VERSION); - int statusColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS); - int lastStatusChangeDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE); - int deletedDateColumnIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.DELETED_DATE); - - int databaseIdIndex = cursor.getColumnIndex(InstanceProviderAPI.InstanceColumns._ID); - - Instance instance = new Instance.Builder() - .displayName(cursor.getString(displayNameColumnIndex)) - .submissionUri(cursor.getString(submissionUriColumnIndex)) - .canEditWhenComplete(cursor.getString(canEditWhenCompleteIndex)) - .instanceFilePath(cursor.getString(instanceFilePathIndex)) - .jrFormId(cursor.getString(jrFormIdColumnIndex)) - .jrVersion(cursor.getString(jrVersionColumnIndex)) - .status(cursor.getString(statusColumnIndex)) - .lastStatusChangeDate(cursor.getLong(lastStatusChangeDateColumnIndex)) - .deletedDate(cursor.getLong(deletedDateColumnIndex)) - .databaseId(cursor.getLong(databaseIdIndex)) - .build(); - - instances.add(instance); - } - } finally { - cursor.close(); - } - } - return instances; - } - - /** - * Returns the values of an instance as a ContentValues object for use with - * {@link org.odk.collect.android.dao.InstancesDao#saveInstance(ContentValues)} (ContentValues)} - * or {@link org.odk.collect.android.dao.InstancesDao#updateInstance(ContentValues, String, String[])} - * - * Does NOT include the database ID. - */ - public static ContentValues getValuesFromInstanceObject(Instance instance) { - ContentValues values = new ContentValues(); - values.put(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME, instance.getDisplayName()); - values.put(InstanceProviderAPI.InstanceColumns.SUBMISSION_URI, instance.getSubmissionUri()); - values.put(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE, instance.getCanEditWhenComplete()); - values.put(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH, instance.getInstanceFilePath()); - values.put(InstanceProviderAPI.InstanceColumns.JR_FORM_ID, instance.getJrFormId()); - values.put(InstanceProviderAPI.InstanceColumns.JR_VERSION, instance.getJrVersion()); - values.put(InstanceProviderAPI.InstanceColumns.STATUS, instance.getStatus()); - values.put(InstanceProviderAPI.InstanceColumns.LAST_STATUS_CHANGE_DATE, instance.getLastStatusChangeDate()); - values.put(InstanceProviderAPI.InstanceColumns.DELETED_DATE, instance.getDeletedDate()); - - return values; - } - - /** - * Returns all forms available through the cursor and closes the cursor. - */ - public static List getFormsFromCursor(Cursor cursor) { - List forms = new ArrayList<>(); - if (cursor != null) { - try { - cursor.moveToPosition(-1); - while (cursor.moveToNext()) { - int idColumnIndex = cursor.getColumnIndex(BaseColumns._ID); - int displayNameColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DISPLAY_NAME); - int descriptionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DESCRIPTION); - int jrFormIdColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_FORM_ID); - int jrVersionColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JR_VERSION); - int formFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH); - int submissionUriColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.SUBMISSION_URI); - int base64RSAPublicKeyColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY); - int md5HashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.MD5_HASH); - int dateColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.DATE); - int jrCacheFilePathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH); - int formMediaPathColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH); - int languageColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LANGUAGE); - int autoSendColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_SEND); - int autoDeleteColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.AUTO_DELETE); - int lastDetectedFormVersionHashColumnIndex = cursor.getColumnIndex(FormsProviderAPI.FormsColumns.LAST_DETECTED_FORM_VERSION_HASH); - - Form form = new Form.Builder() - .id(cursor.getInt(idColumnIndex)) - .displayName(cursor.getString(displayNameColumnIndex)) - .description(cursor.getString(descriptionColumnIndex)) - .jrFormId(cursor.getString(jrFormIdColumnIndex)) - .jrVersion(cursor.getString(jrVersionColumnIndex)) - .formFilePath(cursor.getString(formFilePathColumnIndex)) - .submissionUri(cursor.getString(submissionUriColumnIndex)) - .base64RSAPublicKey(cursor.getString(base64RSAPublicKeyColumnIndex)) - .md5Hash(cursor.getString(md5HashColumnIndex)) - .date(cursor.getLong(dateColumnIndex)) - .jrCacheFilePath(cursor.getString(jrCacheFilePathColumnIndex)) - .formMediaPath(cursor.getString(formMediaPathColumnIndex)) - .language(cursor.getString(languageColumnIndex)) - .autoSend(cursor.getString(autoSendColumnIndex)) - .autoDelete(cursor.getString(autoDeleteColumnIndex)) - .lastDetectedFormVersionHash(cursor.getString(lastDetectedFormVersionHashColumnIndex)) - .build(); - - forms.add(form); - } - } finally { - cursor.close(); - } - } - return forms; - } - - public static ContentValues getValuesFromFormObject(Form form) { - ContentValues values = new ContentValues(); - values.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, form.getDisplayName()); - values.put(FormsProviderAPI.FormsColumns.DESCRIPTION, form.getDescription()); - values.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, form.getJrFormId()); - values.put(FormsProviderAPI.FormsColumns.JR_VERSION, form.getJrVersion()); - values.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, form.getFormFilePath()); - values.put(FormsProviderAPI.FormsColumns.SUBMISSION_URI, form.getSubmissionUri()); - values.put(FormsProviderAPI.FormsColumns.BASE64_RSA_PUBLIC_KEY, form.getBASE64RSAPublicKey()); - values.put(FormsProviderAPI.FormsColumns.MD5_HASH, form.getMD5Hash()); - values.put(FormsProviderAPI.FormsColumns.DATE, form.getDate()); - values.put(FormsProviderAPI.FormsColumns.JRCACHE_FILE_PATH, form.getJrCacheFilePath()); - values.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, form.getFormMediaPath()); - values.put(FormsProviderAPI.FormsColumns.LANGUAGE, form.getLanguage()); - return values; - } -} diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java index f3a4da5cd9f..8439b6feb6b 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DownloadFormListUtils.java @@ -443,7 +443,7 @@ private boolean isNewerFormVersionAvailable(String md5Hash) { } private boolean areNewerMediaFilesAvailable(String formId, String formVersion, List newMediaFiles) { - String mediaDirPath = DatabaseUtils.getAbsoluteFilePath(formsDao.getFormMediaPath(formId, formVersion)); + String mediaDirPath = FileUtils.getAbsoluteFilePath(formsDao.getFormMediaPath(formId, formVersion)); if (mediaDirPath != null) { File[] localMediaFiles = new File(mediaDirPath).listFiles(); if (localMediaFiles != null) { diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java index 879fa8e2afc..52f288432f5 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java @@ -692,4 +692,18 @@ private static class Walker implements Iterator { return next; } } + + public static String getAbsoluteFilePath(String filePath) { + if (filePath == null) { + return null; + } + return filePath.startsWith(Collect.ODK_ROOT) ? filePath : Collect.ODK_ROOT + filePath; + } + + public static String getRelativeFilePath(String filePath) { + if (filePath == null) { + return null; + } + return filePath.startsWith(Collect.ODK_ROOT) ? filePath.substring(Collect.ODK_ROOT.length()) : filePath; + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java index f821456d57f..cbcb428b140 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FormDownloader.java @@ -302,8 +302,8 @@ private UriResult findExistingOrCreateNewUri(File formFile, Map private Uri saveNewForm(Map formInfo, File formFile, String mediaPath) { final ContentValues v = new ContentValues(); - v.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, DatabaseUtils.getRelativeFilePath(formFile.getAbsolutePath())); - v.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, DatabaseUtils.getRelativeFilePath(mediaPath)); + v.put(FormsProviderAPI.FormsColumns.FORM_FILE_PATH, FileUtils.getRelativeFilePath(formFile.getAbsolutePath())); + v.put(FormsProviderAPI.FormsColumns.FORM_MEDIA_PATH, FileUtils.getRelativeFilePath(mediaPath)); v.put(FormsProviderAPI.FormsColumns.DISPLAY_NAME, formInfo.get(FileUtils.TITLE)); v.put(FormsProviderAPI.FormsColumns.JR_VERSION, formInfo.get(FileUtils.VERSION)); v.put(FormsProviderAPI.FormsColumns.JR_FORM_ID, formInfo.get(FileUtils.FORMID)); @@ -356,7 +356,7 @@ private FileResult downloadXform(String formName, String url) FileUtils.deleteAndReport(f); // set the file returned to the file we already had - String existingPath = DatabaseUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); + String existingPath = FileUtils.getAbsoluteFilePath(c.getString(c.getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); f = new File(existingPath); Timber.w("Will use %s", existingPath); } @@ -480,7 +480,7 @@ private static class UriResult { private UriResult(Uri uri, String mediaPath, boolean isNew) { this.uri = uri; - this.mediaPath = DatabaseUtils.getAbsoluteFilePath(mediaPath); + this.mediaPath = FileUtils.getAbsoluteFilePath(mediaPath); this.isNew = isNew; } From b2a492bab22e6edc60a4b26f9b585116e1282162 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 13 Nov 2019 22:41:25 +0100 Subject: [PATCH 12/12] Improved converting paths from absolute to relative and vice versa --- .../odk/collect/android/utilities/FileUtilsTest.java | 3 +++ .../org/odk/collect/android/utilities/FileUtils.java | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java index 981a0c90155..61ad4aa396d 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/utilities/FileUtilsTest.java @@ -33,5 +33,8 @@ public void getRelativeFilePathTest() { assertEquals("/forms/selectext-media/itemsets.csv", FileUtils.getRelativeFilePath("/storage/emulated/0/odk/forms/selectext-media/itemsets.csv")); assertEquals("/forms/selectext-media/itemsets.csv", FileUtils.getRelativeFilePath("/forms/selectext-media/itemsets.csv")); + + assertEquals("/forms/selectext.xml", FileUtils.getRelativeFilePath("/storage/emulated/0/Android/data/org.odk.collect.android/files/forms/selectext.xml")); + assertEquals("/forms/selectext.xml", FileUtils.getRelativeFilePath("/forms/selectext.xml")); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java index 52f288432f5..d50216df037 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/FileUtils.java @@ -697,6 +697,9 @@ public static String getAbsoluteFilePath(String filePath) { if (filePath == null) { return null; } + if (filePath.startsWith("/storage/emulated/0/odk")) { + return Collect.ODK_ROOT + filePath.substring("/storage/emulated/0/odk".length()); + } return filePath.startsWith(Collect.ODK_ROOT) ? filePath : Collect.ODK_ROOT + filePath; } @@ -704,6 +707,12 @@ public static String getRelativeFilePath(String filePath) { if (filePath == null) { return null; } - return filePath.startsWith(Collect.ODK_ROOT) ? filePath.substring(Collect.ODK_ROOT.length()) : filePath; + if (filePath.startsWith("/storage/emulated/0/odk")) { + return filePath.substring("/storage/emulated/0/odk".length()); + } + if (filePath.startsWith("/storage/emulated/0/Android/data/org.odk.collect.android/files")) { + return filePath.substring("/storage/emulated/0/Android/data/org.odk.collect.android/files".length()); + } + return filePath; } }