diff --git a/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskListTest.kt b/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskListTest.kt index c8f62ec8..cfeec992 100644 --- a/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskListTest.kt +++ b/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskListTest.kt @@ -11,7 +11,6 @@ import android.content.ContentUris import android.content.ContentValues import android.database.DatabaseUtils import android.provider.CalendarContract -import at.bitfire.ical4android.impl.TestTask import at.bitfire.ical4android.impl.TestTaskList import net.fortuna.ical4j.model.property.RelatedTo import org.dmfs.tasks.contract.TaskContract @@ -77,9 +76,9 @@ class DmfsTaskListTest(providerName: TaskProvider.ProviderName): child.relatedTo.add(RelatedTo(parent.uid)) // insert child before parent - val childContentUri = TestTask(taskList, child).add() + val childContentUri = DmfsTask(taskList, child, "452a5672-e2b0-434e-92b4-bc70a7a51ef2", null, 0).add() val childId = ContentUris.parseId(childContentUri) - val parentContentUri = TestTask(taskList, parent).add() + val parentContentUri = DmfsTask(taskList, parent, "452a5672-e2b0-434e-92b4-bc70a7a51ef2", null, 0).add() val parentId = ContentUris.parseId(parentContentUri) // OpenTasks should provide the correct relation diff --git a/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskTest.kt b/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskTest.kt index 7404f000..c2318017 100644 --- a/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskTest.kt +++ b/lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskTest.kt @@ -13,7 +13,6 @@ import android.database.DatabaseUtils import android.net.Uri import android.provider.CalendarContract import androidx.core.content.contentValuesOf -import at.bitfire.ical4android.impl.TestTask import at.bitfire.ical4android.impl.TestTaskList import at.bitfire.synctools.storage.LocalStorageException import net.fortuna.ical4j.model.Date @@ -92,7 +91,7 @@ class DmfsTaskTest( val task = Task().apply { taskBuilder() } - val uri = TestTask(taskList!!, task).add() + val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() provider.client.query(uri, null, null, null, null)!!.use { it.moveToNext() val values = ContentValues() @@ -688,7 +687,7 @@ class DmfsTaskTest( task.unknownProperties += XProperty("X-UNKNOWN-PROP", "Unknown Value") // add to task list - val uri = TestTask(taskList!!, task).add() + val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() assertNotNull("Couldn't add task", uri) // read and parse event from calendar provider @@ -721,7 +720,7 @@ class DmfsTaskTest( task.dtStart = DtStart(Date("20150102")) task.due = Due(Date("20150101")) - TestTask(taskList!!, task).add() + DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() } @Test @@ -734,7 +733,7 @@ class DmfsTaskTest( for (i in 1..1050) task.alarms += VAlarm(java.time.Duration.ofMinutes(i.toLong())) - val uri = TestTask(taskList!!, task).add() + val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() val task2 = taskList!!.findById(ContentUris.parseId(uri)) assertEquals(1050, task2.task?.alarms?.size) } @@ -749,7 +748,7 @@ class DmfsTaskTest( task.location = "Sample location" task.dtStart = DtStart("20150501T120000", tzVienna) assertFalse(task.isAllDay()) - val uri = TestTask(taskList!!, task).add() + val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() assertNotNull(uri) val testTask = taskList!!.findById(ContentUris.parseId(uri)) @@ -782,7 +781,7 @@ class DmfsTaskTest( task.dtStart = DtStart(Date("20150501")) task.due = Due(Date("20150502")) assertTrue(task.isAllDay()) - val uri = TestTask(taskList!!, task).add() + val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add() assertNotNull(uri) val testTask = taskList!!.findById(ContentUris.parseId(uri)) @@ -803,16 +802,16 @@ class DmfsTaskTest( @Test fun testGetTimeZone() { // no date/time - var t = TestTask(taskList!!, Task()) + var t = DmfsTask(taskList!!, Task(), "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0) assertEquals(tzDefault, t.getTimeZone()) // dtstart with date (no time) - t = TestTask(taskList!!, Task()) + t = DmfsTask(taskList!!, Task(), "410c19d7-df79-4d65-8146-40b7bec5923b", null, 0) t.task!!.dtStart = DtStart("20150101") assertEquals(tzDefault, t.getTimeZone()) // dtstart with time - t = TestTask(taskList!!, Task()) + t = DmfsTask(taskList!!, Task(), "9dc64544-1816-4f04-b952-e894164467f6", null, 0) t.task!!.dtStart = (DtStart("20150101", tzVienna)) assertEquals(tzVienna, t.getTimeZone()) } diff --git a/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTask.kt b/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTask.kt deleted file mode 100644 index 21113e1b..00000000 --- a/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTask.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of bitfireAT/synctools which is released under GPLv3. - * Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details. - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package at.bitfire.ical4android.impl - -import android.content.ContentValues -import at.bitfire.ical4android.DmfsTask -import at.bitfire.ical4android.DmfsTaskFactory -import at.bitfire.ical4android.DmfsTaskList -import at.bitfire.ical4android.Task - -class TestTask: DmfsTask { - - constructor(taskList: DmfsTaskList, values: ContentValues) - : super(taskList, values) - - constructor(taskList: TestTaskList, task: Task) - : super(taskList, task, "6c2710c3-f82c-4dfa-8738-186b82c35c08", null, 0) - - object Factory: DmfsTaskFactory { - override fun fromProvider(taskList: DmfsTaskList, values: ContentValues) = - TestTask(taskList, values) - } - -} diff --git a/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTaskList.kt b/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTaskList.kt index aa4cedfc..aa6d7644 100644 --- a/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTaskList.kt +++ b/lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestTaskList.kt @@ -16,11 +16,11 @@ import at.bitfire.ical4android.TaskProvider import org.dmfs.tasks.contract.TaskContract class TestTaskList( - account: Account, - provider: ContentProviderClient, - providerName: TaskProvider.ProviderName, - id: Long -): DmfsTaskList(account, provider, providerName, TestTask.Factory, id) { + account: Account, + provider: ContentProviderClient, + providerName: TaskProvider.ProviderName, + id: Long +) : DmfsTaskList(account, provider, providerName, id) { companion object { @@ -33,7 +33,7 @@ class TestTaskList( values.put(TaskContract.TaskListColumns.LIST_COLOR, 0xffff0000) values.put(TaskContract.TaskListColumns.SYNC_ENABLED, 1) values.put(TaskContract.TaskListColumns.VISIBLE, 1) - val uri = DmfsTaskList.create(account, provider.client, provider.name, values) + val uri = create(account, provider.client, provider.name, values) return TestTaskList(account, provider.client, provider.name, ContentUris.parseId(uri)) } @@ -41,9 +41,13 @@ class TestTaskList( } - object Factory: DmfsTaskListFactory { - override fun newInstance(account: Account, provider: ContentProviderClient, providerName: TaskProvider.ProviderName, id: Long) = - TestTaskList(account, provider, providerName, id) + object Factory : DmfsTaskListFactory { + override fun newInstance( + account: Account, + provider: ContentProviderClient, + providerName: TaskProvider.ProviderName, + id: Long + ) = TestTaskList(account, provider, providerName, id) } } diff --git a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTask.kt b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTask.kt index 09d490b5..a8d1ac46 100644 --- a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTask.kt +++ b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTask.kt @@ -64,12 +64,12 @@ import java.util.logging.Logger * The SEQUENCE field is stored in [Tasks.SYNC_VERSION], so don't use [Tasks.SYNC_VERSION] * for anything else. */ -open class DmfsTask( - val taskList: DmfsTaskList<*> +class DmfsTask( + val taskList: DmfsTaskList ) { - protected val logger = Logger.getLogger(javaClass.name) - protected val tzRegistry by lazy { TimeZoneRegistryFactory.getInstance().createRegistry() } + private val logger = Logger.getLogger(javaClass.name) + private val tzRegistry by lazy { TimeZoneRegistryFactory.getInstance().createRegistry() } var id: Long? = null var syncId: String? = null @@ -77,14 +77,14 @@ open class DmfsTask( var flags: Int = 0 - constructor(taskList: DmfsTaskList<*>, values: ContentValues): this(taskList) { + constructor(taskList: DmfsTaskList, values: ContentValues): this(taskList) { id = values.getAsLong(Tasks._ID) syncId = values.getAsString(Tasks._SYNC_ID) eTag = values.getAsString(COLUMN_ETAG) flags = values.getAsInteger(COLUMN_FLAGS) ?: 0 } - constructor(taskList: DmfsTaskList<*>, task: Task, syncId: String?, eTag: String?, flags: Int): this(taskList) { + constructor(taskList: DmfsTaskList, task: Task, syncId: String?, eTag: String?, flags: Int): this(taskList) { this.task = task this.syncId = syncId this.eTag = eTag @@ -160,7 +160,7 @@ open class DmfsTask( throw FileNotFoundException("Couldn't find task #$id") } - protected fun populateTask(values: ContentValues) { + private fun populateTask(values: ContentValues) { val task = requireNotNull(task) task.uid = values.getAsString(Tasks._UID) @@ -267,7 +267,7 @@ open class DmfsTask( values.getAsString(Tasks.RRULE)?.let { task.rRule = RRule(it) } } - protected fun populateProperty(row: ContentValues) { + private fun populateProperty(row: ContentValues) { logger.log(Level.FINER, "Found property", row) val task = requireNotNull(task) @@ -287,7 +287,7 @@ open class DmfsTask( } } - protected fun populateAlarm(row: ContentValues) { + private fun populateAlarm(row: ContentValues) { val task = requireNotNull(task) val props = PropertyList() @@ -315,7 +315,7 @@ open class DmfsTask( task.alarms += VAlarm(props) } - protected fun populateRelatedTo(row: ContentValues) { + private fun populateRelatedTo(row: ContentValues) { val uid = row.getAsString(Relation.RELATED_UID) if (uid == null) { logger.warning("Task relation doesn't refer to same task list; can't be synchronized") @@ -380,7 +380,11 @@ open class DmfsTask( return ContentUris.withAppendedId(Tasks.getContentUri(taskList.providerName.authority), existingId) } - protected fun insertProperties(batch: TasksBatchOperation, idxTask: Int?) { + fun update(values: ContentValues) { + taskList.provider.update(taskSyncURI(), values, null, null) + } + + private fun insertProperties(batch: TasksBatchOperation, idxTask: Int?) { insertAlarms(batch, idxTask) insertCategories(batch, idxTask) insertComment(batch, idxTask) @@ -388,7 +392,7 @@ open class DmfsTask( insertUnknownProperties(batch, idxTask) } - protected fun insertAlarms(batch: TasksBatchOperation, idxTask: Int?) { + private fun insertAlarms(batch: TasksBatchOperation, idxTask: Int?) { val task = requireNotNull(task) for (alarm in task.alarms) { val (alarmRef, minutes) = ICalendar.vAlarmToMin( @@ -430,7 +434,7 @@ open class DmfsTask( } } - protected fun insertCategories(batch: TasksBatchOperation, idxTask: Int?) { + private fun insertCategories(batch: TasksBatchOperation, idxTask: Int?) { for (category in requireNotNull(task).categories) { val builder = CpoBuilder.newInsert(taskList.tasksPropertiesSyncUri()) .withTaskId(Category.TASK_ID, idxTask) @@ -441,7 +445,7 @@ open class DmfsTask( } } - protected fun insertComment(batch: TasksBatchOperation, idxTask: Int?) { + private fun insertComment(batch: TasksBatchOperation, idxTask: Int?) { val comment = requireNotNull(task).comment ?: return val builder = CpoBuilder.newInsert(taskList.tasksPropertiesSyncUri()) .withTaskId(Comment.TASK_ID, idxTask) @@ -451,7 +455,7 @@ open class DmfsTask( batch += builder } - protected fun insertRelatedTo(batch: TasksBatchOperation, idxTask: Int?) { + private fun insertRelatedTo(batch: TasksBatchOperation, idxTask: Int?) { for (relatedTo in requireNotNull(task).relatedTo) { val relType = when ((relatedTo.getParameter(Parameter.RELTYPE) as RelType?)) { RelType.CHILD -> @@ -471,7 +475,7 @@ open class DmfsTask( } } - protected fun insertUnknownProperties(batch: TasksBatchOperation, idxTask: Int?) { + private fun insertUnknownProperties(batch: TasksBatchOperation, idxTask: Int?) { for (property in requireNotNull(task).unknownProperties) { if (property.value.length > UnknownProperty.MAX_UNKNOWN_PROPERTY_SIZE) { logger.warning("Ignoring unknown property with ${property.value.length} octets (too long)") @@ -491,7 +495,7 @@ open class DmfsTask( return taskList.provider.delete(taskSyncURI(), null, null) } - protected fun buildTask(builder: CpoBuilder, update: Boolean) { + private fun buildTask(builder: CpoBuilder, update: Boolean) { if (!update) builder .withValue(Tasks.LIST_ID, taskList.id) @@ -602,7 +606,7 @@ open class DmfsTask( } - protected fun CpoBuilder.withTaskId(column: String, idxTask: Int?): CpoBuilder { + private fun CpoBuilder.withTaskId(column: String, idxTask: Int?): CpoBuilder { if (idxTask != null) withValueBackReference(column, idxTask) else @@ -611,7 +615,7 @@ open class DmfsTask( } - protected fun taskSyncURI(loadProperties: Boolean = false): Uri { + private fun taskSyncURI(loadProperties: Boolean = false): Uri { val id = requireNotNull(id) return ContentUris.withAppendedId(taskList.tasksSyncUri(loadProperties), id) } diff --git a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskFactory.kt b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskFactory.kt deleted file mode 100644 index 55e3c6c0..00000000 --- a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskFactory.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This file is part of bitfireAT/synctools which is released under GPLv3. - * Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details. - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package at.bitfire.ical4android - -import android.content.ContentValues - -interface DmfsTaskFactory { - - fun fromProvider(taskList: DmfsTaskList, values: ContentValues): T - -} diff --git a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskList.kt b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskList.kt index 44435336..a060fe98 100644 --- a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskList.kt +++ b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskList.kt @@ -33,11 +33,10 @@ import java.util.logging.Logger * Represents a locally stored task list, containing [DmfsTask]s (tasks). * Communicates with tasks.org-compatible content providers (currently tasks.org and OpenTasks) to store the tasks. */ -open class DmfsTaskList( +open class DmfsTaskList( val account: Account, val provider: ContentProviderClient, val providerName: TaskProvider.ProviderName, - val taskFactory: DmfsTaskFactory, val id: Long ) { @@ -133,18 +132,18 @@ open class DmfsTaskList( * * @return events from this task list which match the selection */ - fun queryTasks(_where: String? = null, _whereArgs: Array? = null): List { + fun queryTasks(_where: String? = null, _whereArgs: Array? = null): List { val where = "(${_where ?: "1"}) AND ${Tasks.LIST_ID}=?" val whereArgs = (_whereArgs ?: arrayOf()) + id.toString() - val tasks = LinkedList() + val tasks = LinkedList() provider.query( tasksSyncUri(), null, where, whereArgs, null )?.use { cursor -> while (cursor.moveToNext()) - tasks += taskFactory.fromProvider(this, cursor.toContentValues()) + tasks += DmfsTask(this, cursor.toContentValues()) } return tasks } @@ -201,7 +200,7 @@ open class DmfsTaskList( ?: throw LocalStorageException("Couldn't create task list (empty result from provider)") } - fun > findByID( + fun findByID( account: Account, provider: ContentProviderClient, providerName: TaskProvider.ProviderName, @@ -224,7 +223,7 @@ open class DmfsTaskList( throw FileNotFoundException() } - fun > find( + fun find( account: Account, factory: DmfsTaskListFactory, provider: ContentProviderClient, @@ -253,4 +252,14 @@ open class DmfsTaskList( } + // default factory (will be removed as soon as DmfsTaskList is not open anymore) + object Factory : DmfsTaskListFactory { + override fun newInstance( + account: Account, + provider: ContentProviderClient, + providerName: TaskProvider.ProviderName, + id: Long + ): DmfsTaskList = DmfsTaskList(account, provider, providerName, id) + } + } diff --git a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskListFactory.kt b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskListFactory.kt index 8cb26b4d..dce50b08 100644 --- a/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskListFactory.kt +++ b/lib/src/main/kotlin/at/bitfire/ical4android/DmfsTaskListFactory.kt @@ -9,7 +9,7 @@ package at.bitfire.ical4android import android.accounts.Account import android.content.ContentProviderClient -interface DmfsTaskListFactory> { +interface DmfsTaskListFactory { fun newInstance(account: Account, provider: ContentProviderClient, providerName: TaskProvider.ProviderName, id: Long): T