LocalTask: Don't subclass DmfsTask (#1862)

* LocalTask: Don't subclass DmfsTask

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Adapt usages

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Update synctools

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
This commit is contained in:
Sunik Kupfer
2025-12-10 14:37:23 +01:00
committed by GitHub
parent 29240ea16f
commit b354bfebc2
5 changed files with 46 additions and 49 deletions

View File

@@ -10,37 +10,49 @@ import android.content.Context
import android.net.Uri
import androidx.core.content.contentValuesOf
import at.bitfire.ical4android.DmfsTask
import at.bitfire.ical4android.DmfsTaskFactory
import at.bitfire.ical4android.DmfsTaskList
import at.bitfire.ical4android.Task
import at.bitfire.ical4android.TaskProvider
import com.google.common.base.MoreObjects
import org.dmfs.tasks.contract.TaskContract.Tasks
import java.util.Optional
import java.util.logging.Logger
/**
* Represents a Dmfs Task (OpenTasks and Tasks.org) entry
*/
class LocalTask: DmfsTask, LocalResource {
class LocalTask(
val dmfsTask: DmfsTask
): LocalResource {
val logger: Logger = Logger.getLogger(javaClass.name)
// LocalResource implementation
override val id: Long?
get() = dmfsTask.id
override var fileName: String?
get() = syncId
set(value) { syncId = value }
get() = dmfsTask.syncId
set(value) { dmfsTask.syncId = value }
override var eTag: String?
get() = dmfsTask.eTag
set(value) { dmfsTask.eTag = value }
/**
* Note: Schedule-Tag for tasks is not supported
*/
override var scheduleTag: String? = null
override val flags: Int
get() = dmfsTask.flags
constructor(taskList: DmfsTaskList<*>, task: Task, fileName: String?, eTag: String?, flags: Int)
: super(taskList, task, fileName, eTag, flags)
fun add() = dmfsTask.add()
private constructor(taskList: DmfsTaskList<*>, values: ContentValues)
: super(taskList, values)
fun update(data: Task) = dmfsTask.update(data)
/* custom queries */
fun delete() = dmfsTask.delete()
override fun clearDirty(fileName: Optional<String>, eTag: String?, scheduleTag: String?) {
if (scheduleTag != null)
@@ -49,46 +61,33 @@ class LocalTask: DmfsTask, LocalResource {
val values = ContentValues(4)
if (fileName.isPresent)
values.put(Tasks._SYNC_ID, fileName.get())
values.put(COLUMN_ETAG, eTag)
values.put(Tasks.SYNC_VERSION, task!!.sequence)
values.put(DmfsTask.COLUMN_ETAG, eTag)
values.put(Tasks.SYNC_VERSION, dmfsTask.task!!.sequence)
values.put(Tasks._DIRTY, 0)
taskList.provider.update(taskSyncURI(), values, null, null)
dmfsTask.update(values)
if (fileName.isPresent)
this.fileName = fileName.get()
this.eTag = eTag
}
fun update(data: Task, fileName: String?, eTag: String?, scheduleTag: String?, flags: Int) {
if (scheduleTag != null)
logger.fine("Schedule-Tag for tasks not supported, won't save")
this.fileName = fileName
this.eTag = eTag
this.flags = flags
// processes this.{fileName, eTag, scheduleTag, flags} and resets DIRTY flag
update(data)
}
override fun updateFlags(flags: Int) {
if (id != null) {
val values = contentValuesOf(COLUMN_FLAGS to flags)
taskList.provider.update(taskSyncURI(), values, null, null)
val values = contentValuesOf(DmfsTask.COLUMN_FLAGS to flags)
dmfsTask.update(values)
}
this.flags = flags
dmfsTask.flags = flags
}
override fun updateSequence(sequence: Int) = throw NotImplementedError()
override fun updateUid(uid: String) {
val values = contentValuesOf(Tasks._UID to uid)
taskList.provider.update(taskSyncURI(), values, null, null)
dmfsTask.update(values)
}
override fun deleteLocal() {
delete()
dmfsTask.delete()
}
override fun resetDeleted() {
@@ -112,9 +111,9 @@ class LocalTask: DmfsTask, LocalResource {
.toString()
override fun getViewUri(context: Context): Uri? = id?.let { id ->
when (taskList.providerName) {
when (dmfsTask.taskList.providerName) {
TaskProvider.ProviderName.OpenTasks -> {
val contentUri = Tasks.getContentUri(taskList.providerName.authority)
val contentUri = Tasks.getContentUri(dmfsTask.taskList.providerName.authority)
ContentUris.withAppendedId(contentUri, id)
}
// Tasks.org can't handle view content URIs (missing intent-filter)
@@ -123,10 +122,4 @@ class LocalTask: DmfsTask, LocalResource {
}
}
object Factory: DmfsTaskFactory<LocalTask> {
override fun fromProvider(taskList: DmfsTaskList<*>, values: ContentValues) =
LocalTask(taskList, values)
}
}

View File

@@ -26,7 +26,7 @@ class LocalTaskList private constructor(
provider: ContentProviderClient,
providerName: TaskProvider.ProviderName,
id: Long
): DmfsTaskList<LocalTask>(account, provider, providerName, LocalTask.Factory, id), LocalCollection<LocalTask> {
): DmfsTaskList(account, provider, providerName, id), LocalCollection<LocalTask> {
private val logger = Logger.getGlobal()
@@ -51,10 +51,11 @@ class LocalTaskList private constructor(
}
override fun findDeleted() = queryTasks(Tasks._DELETED, null)
.map { LocalTask(it) }
override fun findDirty(): List<LocalTask> {
val tasks = queryTasks(Tasks._DIRTY, null)
for (localTask in tasks) {
val dmfsTasks = queryTasks(Tasks._DIRTY, null)
for (localTask in dmfsTasks) {
try {
val task = requireNotNull(localTask.task)
val sequence = task.sequence
@@ -66,11 +67,14 @@ class LocalTaskList private constructor(
logger.log(Level.WARNING, "Couldn't check/increase sequence", e)
}
}
return tasks
return dmfsTasks.map { LocalTask(it) }
}
override fun findByName(name: String) =
queryTasks("${Tasks._SYNC_ID}=?", arrayOf(name)).firstOrNull()
queryTasks("${Tasks._SYNC_ID}=?", arrayOf(name))
.firstOrNull()?.let {
LocalTask(it)
}
override fun markNotDirty(flags: Int): Int {

View File

@@ -12,7 +12,6 @@ import android.provider.CalendarContract.Calendars
import android.provider.CalendarContract.Reminders
import androidx.core.content.ContextCompat
import androidx.core.content.contentValuesOf
import at.bitfire.davdroid.resource.LocalTask
import at.bitfire.ical4android.DmfsTask
import at.bitfire.ical4android.TaskProvider
import at.techbee.jtx.JtxContract.asSyncAdapter

View File

@@ -25,6 +25,7 @@ import at.bitfire.davdroid.resource.LocalTaskList
import at.bitfire.davdroid.resource.SyncState
import at.bitfire.davdroid.util.DavUtils
import at.bitfire.davdroid.util.DavUtils.lastSegment
import at.bitfire.ical4android.DmfsTask
import at.bitfire.ical4android.Task
import at.bitfire.synctools.exception.InvalidICalendarException
import dagger.assisted.Assisted
@@ -103,7 +104,7 @@ class TasksSyncManager @AssistedInject constructor(
override fun syncAlgorithm() = SyncAlgorithm.PROPFIND_REPORT
override fun generateUpload(resource: LocalTask): GeneratedResource {
val task = requireNotNull(resource.task)
val task = requireNotNull(resource.dmfsTask.task)
logger.log(Level.FINE, "Preparing upload of task ${resource.id}", task)
// get/create UID
@@ -191,7 +192,7 @@ class TasksSyncManager @AssistedInject constructor(
local.update(newData)
} else {
logger.log(Level.INFO, "Adding $fileName to local task list", newData)
val newLocal = LocalTask(localCollection, newData, fileName, eTag, LocalResource.FLAG_REMOTELY_PRESENT)
val newLocal = LocalTask(DmfsTask(localCollection, newData, fileName, eTag, LocalResource.FLAG_REMOTELY_PRESENT))
SyncException.wrapWithLocalResource(newLocal) {
newLocal.add()
}

View File

@@ -20,7 +20,7 @@ androidx-test-junit = "1.3.0"
androidx-work = "2.11.0"
bitfire-cert4android = "42d883e958"
bitfire-dav4jvm = "de16b12343"
bitfire-synctools = "5fb54ec88c"
bitfire-synctools = "de78892b5c"
compose-accompanist = "0.37.3"
compose-bom = "2025.11.01"
conscrypt = "2.5.3"