Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.impl.TestCalendar
import at.bitfire.ical4android.impl.TestEvent
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.synctools.LocalStorageException
import net.fortuna.ical4j.model.property.Attendee
import net.fortuna.ical4j.model.property.DtEnd
import net.fortuna.ical4j.model.property.DtStart
Expand Down Expand Up @@ -117,7 +118,7 @@ class BatchOperationTest {
}
}

@Test(expected = CalendarStorageException::class)
@Test(expected = LocalStorageException::class)
fun testLargeTransactionSingleRow() {
val event = Event()
event.uid = "sample1@testLargeTransaction"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.net.Uri
import at.bitfire.ical4android.impl.TestTask
import at.bitfire.ical4android.impl.TestTaskList
import at.bitfire.ical4android.util.DateUtils
import at.bitfire.synctools.LocalStorageException
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateList
import net.fortuna.ical4j.model.DateTime
Expand Down Expand Up @@ -694,7 +695,7 @@ class DmfsTaskTest(
}
}

@Test(expected = CalendarStorageException::class)
@Test(expected = LocalStorageException::class)
fun testAddTaskWithInvalidDue() {
val task = Task()
task.uid = "[email protected]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.test.filters.MediumTest
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.synctools.LocalStorageException
import at.bitfire.vcard4android.impl.TestAddressBook
import at.bitfire.vcard4android.property.XAbDate
import ezvcard.VCardVersion
Expand Down Expand Up @@ -169,7 +170,7 @@ class AndroidContactTest {
}
}

@Test(expected = ContactsStorageException::class)
@Test(expected = LocalStorageException::class)
fun testLargeTransactionSingleRow() {
val vcard = Contact()
vcard.displayName = "Large Transaction (one row which is too large)"
Expand Down
10 changes: 6 additions & 4 deletions lib/src/main/kotlin/at/bitfire/ical4android/AndroidEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import at.bitfire.ical4android.util.TimeApiExtensions.toLocalDate
import at.bitfire.ical4android.util.TimeApiExtensions.toLocalTime
import at.bitfire.ical4android.util.TimeApiExtensions.toRfc5545Duration
import at.bitfire.ical4android.util.TimeApiExtensions.toZonedDateTime
import at.bitfire.synctools.LocalStorageException
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateList
import net.fortuna.ical4j.model.DateTime
Expand Down Expand Up @@ -221,7 +222,8 @@ abstract class AndroidEvent(
}

val allDay = (row.getAsInteger(Events.ALL_DAY) ?: 0) != 0
val tsStart = row.getAsLong(Events.DTSTART) ?: throw CalendarStorageException("Found event without DTSTART")
val tsStart = row.getAsLong(Events.DTSTART)
?: throw LocalStorageException("Found event without DTSTART")

var tsEnd = row.getAsLong(Events.DTEND)
var duration = // only use DURATION of DTEND is not defined
Expand Down Expand Up @@ -566,7 +568,7 @@ abstract class AndroidEvent(
*
* @return content URI of the created event
*
* @throws CalendarStorageException when the calendar provider doesn't return a result row
* @throws LocalStorageException when the calendar provider doesn't return a result row
* @throws RemoteException on calendar provider errors
*/
fun add(): Uri {
Expand All @@ -575,7 +577,7 @@ abstract class AndroidEvent(
batch.commit()

val resultUri = batch.getResult(idxEvent)?.uri
?: throw CalendarStorageException("Empty result from content provider when adding event")
?: throw LocalStorageException("Empty result from content provider when adding event")
id = ContentUris.parseId(resultUri)
return resultUri
}
Expand Down Expand Up @@ -691,7 +693,7 @@ abstract class AndroidEvent(
/**
* Updates an already existing event in the calendar storage with the values
* from the instance.
* @throws CalendarStorageException when the calendar provider doesn't return a result row
* @throws LocalStorageException when the calendar provider doesn't return a result row
* @throws RemoteException on calendar provider errors
*/
fun update(event: Event): Uri {
Expand Down
14 changes: 8 additions & 6 deletions lib/src/main/kotlin/at/bitfire/ical4android/BatchOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.content.OperationApplicationException
import android.net.Uri
import android.os.RemoteException
import android.os.TransactionTooLargeException
import at.bitfire.synctools.LocalStorageException
import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger
Expand Down Expand Up @@ -51,7 +52,7 @@ class BatchOperation(
* @throws RemoteException on calendar provider errors. In case of [android.os.DeadObjectException],
* the provider has probably been killed/crashed or the calling process is cached and thus IPC is frozen (Android 14+).
*
* @throws CalendarStorageException if
* @throws LocalStorageException if
*
* - the transaction is too large and can't be split (wrapped [TransactionTooLargeException])
* - the batch can't be processed (wrapped [OperationApplicationException])
Expand Down Expand Up @@ -94,7 +95,7 @@ class BatchOperation(
* @throws RemoteException on calendar provider errors. In case of [android.os.DeadObjectException],
* the provider has probably been killed/crashed or the calling process is cached and thus IPC is frozen (Android 14+).
*
* @throws CalendarStorageException if
* @throws LocalStorageException if
*
* - the transaction is too large and can't be split (wrapped [TransactionTooLargeException])
* - the batch can't be processed (wrapped [OperationApplicationException])
Expand All @@ -115,15 +116,15 @@ class BatchOperation(
System.arraycopy(partResults, 0, results, start, partResults.size)

} catch (e: OperationApplicationException) {
throw CalendarStorageException("Couldn't apply batch operation", e)
throw LocalStorageException("Couldn't apply batch operation", e)

} catch (e: RuntimeException) {
throw CalendarStorageException("Content provider threw a runtime exception", e)
throw LocalStorageException("Content provider threw a runtime exception", e)

} catch(e: TransactionTooLargeException) {
if (end <= start + 1)
// only one operation, can't be split
throw CalendarStorageException("Can't transfer data to content provider (too large data row can't be split)", e)
throw LocalStorageException("Can't transfer data to content provider (too large data row can't be split)", e)

logger.warning("Transaction too large, splitting (losing atomicity)")
val mid = start + (end - start)/2
Expand All @@ -148,7 +149,8 @@ class BatchOperation(
val originalIdx = backref.originalIndex
if (originalIdx < start) {
// back reference is outside of the current batch, get result from previous execution ...
val resultUri = results[originalIdx]?.uri ?: throw CalendarStorageException("Referenced operation didn't produce a valid result")
val resultUri = results[originalIdx]?.uri
?: throw LocalStorageException("Referenced operation didn't produce a valid result")
val resultId = ContentUris.parseId(resultUri)
// ... and use result directly instead of using a back reference
cpoBuilder .removeValueBackReference(backrefKey)
Expand Down

This file was deleted.

4 changes: 3 additions & 1 deletion lib/src/main/kotlin/at/bitfire/ical4android/DmfsTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import at.bitfire.ical4android.BatchOperation.CpoBuilder
import at.bitfire.ical4android.util.AndroidTimeUtils
import at.bitfire.ical4android.util.DateUtils
import at.bitfire.ical4android.util.MiscUtils.toValues
import at.bitfire.synctools.LocalStorageException
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateTime
import net.fortuna.ical4j.model.Parameter
Expand Down Expand Up @@ -343,7 +344,8 @@ abstract class DmfsTask(

batch.commit()

val resultUri = batch.getResult(0)?.uri ?: throw CalendarStorageException("Empty result from provider when adding a task")
val resultUri = batch.getResult(0)?.uri
?: throw LocalStorageException("Empty result from provider when adding a task")
id = ContentUris.parseId(resultUri)
return resultUri
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.net.Uri
import androidx.annotation.CallSuper
import at.bitfire.ical4android.util.MiscUtils.asSyncAdapter
import at.bitfire.ical4android.util.MiscUtils.toValues
import at.bitfire.synctools.LocalStorageException
import org.dmfs.tasks.contract.TaskContract
import org.dmfs.tasks.contract.TaskContract.Property.Relation
import org.dmfs.tasks.contract.TaskContract.TaskLists
Expand Down Expand Up @@ -48,7 +49,7 @@ abstract class DmfsTaskList<out T : DmfsTask>(
val url = TaskLists.getContentUri(providerName.authority).asSyncAdapter(account)
logger.log(Level.FINE, "Creating ${providerName.authority} task list", info)
return provider.insert(url, info)
?: throw CalendarStorageException("Couldn't create task list (empty result from provider)")
?: throw LocalStorageException("Couldn't create task list (empty result from provider)")
}

fun <T : DmfsTaskList<DmfsTask>> findByID(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.content.ContentValues
import android.content.Context
import android.net.Uri
import at.bitfire.ical4android.util.MiscUtils.toValues
import at.bitfire.synctools.LocalStorageException
import at.techbee.jtx.JtxContract
import at.techbee.jtx.JtxContract.asSyncAdapter
import net.fortuna.ical4j.model.Calendar
Expand All @@ -36,7 +37,7 @@ open class JtxCollection<out T: JtxICalObject>(val account: Account,
fun create(account: Account, client: ContentProviderClient, values: ContentValues): Uri {
logger.log(Level.FINE, "Creating jtx Board collection", values)
return client.insert(JtxContract.JtxCollection.CONTENT_URI.asSyncAdapter(account), values)
?: throw CalendarStorageException("Couldn't create JTX Collection")
?: throw LocalStorageException("Couldn't create JTX Collection")
}

fun<T: JtxCollection<JtxICalObject>> find(account: Account, client: ContentProviderClient, context: Context, factory: JtxCollectionFactory<T>, where: String?, whereArgs: Array<String>?): List<T> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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.synctools

/**
* Indicates a problem with a local storage operation, such as failing to insert or update a row
* in contacts or calendar storage.
*
* @param message A detail message explaining the cause of the error.
* @param cause The throwable that caused this exception, if any.
*/
class LocalStorageException @JvmOverloads constructor(
message: String?,
cause: Throwable? = null
) : Exception(message, cause)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import android.provider.ContactsContract
import android.provider.ContactsContract.RawContacts
import android.provider.ContactsContract.RawContacts.Data
import androidx.annotation.CallSuper
import at.bitfire.synctools.LocalStorageException
import at.bitfire.vcard4android.contactrow.ContactProcessor
import at.bitfire.vcard4android.contactrow.PhotoBuilder
import java.io.FileNotFoundException
Expand Down Expand Up @@ -124,7 +125,8 @@ open class AndroidContact(
insertDataRows(batch)

batch.commit()
val resultUri = batch.getResult(0)?.uri ?: throw ContactsStorageException("Empty result from content provider when adding contact")
val resultUri = batch.getResult(0)?.uri
?: throw LocalStorageException("Empty result from content provider when adding contact")
id = ContentUris.parseId(resultUri)

getContact().photo?.let { photo ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import android.provider.ContactsContract.Groups
import android.provider.ContactsContract.RawContacts
import android.provider.ContactsContract.RawContacts.Data
import androidx.annotation.CallSuper
import at.bitfire.synctools.LocalStorageException
import java.io.FileNotFoundException
import java.util.logging.Logger

Expand Down Expand Up @@ -128,7 +129,7 @@ open class AndroidGroup(
* Creates a group with data taken from the constructor.
* @return number of affected rows
* @throws RemoteException on contact provider errors
* @throws ContactsStorageException when the group can't be added
* @throws LocalStorageException when the group can't be added
*/
fun add(): Uri {
val values = contentValues()
Expand All @@ -138,7 +139,7 @@ open class AndroidGroup(
if (addressBook.readOnly)
values.put(Groups.GROUP_IS_READ_ONLY, 1)
val uri = addressBook.provider!!.insert(addressBook.syncAdapterURI(Groups.CONTENT_URI), values)
?: throw ContactsStorageException("Empty result from content provider when adding group")
?: throw LocalStorageException("Empty result from content provider when adding group")
id = ContentUris.parseId(uri)
return uri
}
Expand Down
14 changes: 8 additions & 6 deletions lib/src/main/kotlin/at/bitfire/vcard4android/BatchOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.content.OperationApplicationException
import android.net.Uri
import android.os.RemoteException
import android.os.TransactionTooLargeException
import at.bitfire.synctools.LocalStorageException
import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger
Expand Down Expand Up @@ -57,7 +58,7 @@ class BatchOperation(
* @throws RemoteException on calendar provider errors. In case of [android.os.DeadObjectException],
* the provider has probably been killed/crashed or the calling process is cached and thus IPC is frozen (Android 14+).
*
* @throws ContactsStorageException if
* @throws LocalStorageException if
*
* - the transaction is too large and can't be split (wrapped [TransactionTooLargeException])
* - the batch can't be processed (wrapped [OperationApplicationException])
Expand Down Expand Up @@ -100,7 +101,7 @@ class BatchOperation(
* @throws RemoteException on calendar provider errors. In case of [android.os.DeadObjectException],
* the provider has probably been killed/crashed or the calling process is cached and thus IPC is frozen (Android 14+).
*
* @throws ContactsStorageException if
* @throws LocalStorageException if
*
* - the transaction is too large and can't be split (wrapped [TransactionTooLargeException])
* - the batch can't be processed (wrapped [OperationApplicationException])
Expand All @@ -122,15 +123,15 @@ class BatchOperation(
System.arraycopy(partResults, 0, results, start, partResults.size)

} catch (e: OperationApplicationException) {
throw ContactsStorageException("Couldn't apply batch operation", e)
throw LocalStorageException("Couldn't apply batch operation", e)

} catch (e: RuntimeException) {
throw ContactsStorageException("Content provider threw a runtime exception", e)
throw LocalStorageException("Content provider threw a runtime exception", e)

} catch(e: TransactionTooLargeException) {
if (end <= start + 1)
// only one operation, can't be split
throw ContactsStorageException("Can't transfer data to content provider (too large data row can't be split)", e)
throw LocalStorageException("Can't transfer data to content provider (too large data row can't be split)", e)

logger.warning("Transaction too large, splitting (losing atomicity)")
val mid = start + (end - start)/2
Expand All @@ -154,7 +155,8 @@ class BatchOperation(
val originalIdx = backref.originalIndex
if (originalIdx < start) {
// back reference is outside of the current batch, get result from previous execution ...
val resultUri = results[originalIdx]?.uri ?: throw ContactsStorageException("Referenced operation didn't produce a valid result")
val resultUri = results[originalIdx]?.uri
?: throw LocalStorageException("Referenced operation didn't produce a valid result")
val resultId = ContentUris.parseId(resultUri)
// ... and use result directly instead of using a back reference
cpoBuilder .removeValueBackReference(backrefKey)
Expand Down

This file was deleted.