Skip to content

Migrate to synctools library for iCalendar handling#2348

Open
patrickunterwegs wants to merge 3 commits into
migrate-to-synctools-within-davx5from
claude/synctools-davx5-migration-ebj88o
Open

Migrate to synctools library for iCalendar handling#2348
patrickunterwegs wants to merge 3 commits into
migrate-to-synctools-within-davx5from
claude/synctools-davx5-migration-ebj88o

Conversation

@patrickunterwegs

Copy link
Copy Markdown
Member

Summary

Refactored Ical4androidUtil to use the new synctools library for iCalendar parsing, object mapping, and storage operations, replacing the previous ical4android-based implementation.

Key Changes

  • Updated imports: Replaced ical4android imports with synctools equivalents (ICalendarParser, CalendarUidSplitter, JtxObjectBuilder, JtxObjectHandler, etc.)

  • Refactored getICSFormatForCollectionFromProvider():

    • Now uses JtxCollectionProvider and JtxObjectHandler for mapping objects to iCalendar components
    • Iterates through main jtx objects and their exceptions separately
    • Properly handles resource cleanup with try-finally block
  • Refactored writeICSFormatFromProviderToOS():

    • Simplified to use new componentsForObject() helper method
    • Uses JtxObjectHandler for consistent component mapping
    • Improved error handling and resource management
  • Refactored insertFromReader():

    • Replaced JtxICalObject.fromReader() with ICalendarParser and CalendarUidSplitter
    • Uses JtxObjectBuilder to construct jtx objects from parsed components
    • Uses JtxRecurringCollection for proper insertion of objects with exceptions
    • Updated sequence comparison logic to work with new data structures
  • Added helper methods:

    • jtxObjectHandler(): Creates a configured JtxObjectHandler with attachment fetching
    • componentsForObject(): Maps a main jtx object and its exceptions to iCalendar components
    • buildCalendar(): Constructs a Calendar object from components
    • writeComponents(): Overloaded methods to write components to OutputStream or Writer
  • Removed legacy classes: Deleted LocalJtxICalObject and LocalJtxCollection wrapper classes (now handled by synctools)

  • Updated test expectations: Adjusted Ical4androidUtilTest to reflect that synctools' CalendarUidSplitter merges duplicate components with the same UID during parsing

Implementation Details

  • All public methods now properly acquire and release content provider clients with try-finally blocks
  • Exception handling logs warnings and returns appropriate default values (null or empty pairs)
  • The new implementation leverages synctools' built-in support for handling recurrence exceptions and attachment fetching
  • Component mapping is now centralized through JtxObjectHandler for consistency across export operations

https://claude.ai/code/session_011JEizQuqZkmoSJf6saEPDH

claude added 3 commits July 16, 2026 15:35
The davx5-ose synctools submodule replaced the former fat JtxICalObject /
JtxCollection<T> classes with an Entity + builder/handler design and moved
the packages from at.bitfire.ical4android to at.bitfire.synctools.

Rewrite the ICS import/export helpers accordingly, mirroring DAVx5's own
JtxSyncManager usage:

- Look up collections via JtxCollectionProvider.getCollection().
- Export: map jtx objects (main + recurrence exceptions) to VJOURNAL/VTODO
  with JtxObjectHandler + AndroidAttachmentFetcher, then build and output a
  single VCALENDAR via ical4j.
- Import: parse with ICalendarParser, group components by UID with
  CalendarUidSplitter, build entities with JtxObjectBuilder, mark them dirty
  and insert via JtxRecurringCollection; keep UID/sequence de-duplication
  against existing entries.
- Drop the obsolete LocalJtxICalObject / LocalJtxCollection subclasses.
- Acquire and close the content provider client per call.

Also point ICalObject.kt's TimeApiExtensions.toLocalDate import at the new
at.bitfire.synctools.util package.

The in-file duplicate-UID import test now expects 0 skipped, because
CalendarUidSplitter already collapses same-UID/same-RECURRENCE-ID components
during parsing (per RFC 5545); DB-level skipping on re-import is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JEizQuqZkmoSJf6saEPDH
The jitpack artifact com.github.bitfireat.davx5-ose:synctools:v4.5.17.1-ose
does not resolve (jitpack can't build/serve the davx5-ose multi-module
project), which fails the build before any source compiles.

Consume synctools from source instead:
- Add davx5-ose as a Git submodule pinned to tag v4.5.17.1-ose.
- Include it as a Gradle composite build in settings.gradle.kts, with an
  explicit dependencySubstitution mapping the version-catalog coordinate
  (libs.synctools) to the local :synctools project. The explicit target keeps
  only :synctools and davx5-ose's build-logic configured, not :app-ose/:core.

jtxBoard and davx5-ose v4.5.17.1-ose are version-aligned (Gradle 9.6.1,
AGP 9.2.1, Kotlin 2.4.0, KSP 2.3.9, Java toolchain 21), synctools' own
dependencies come from Maven Central/Google, and all CI workflows already
check out submodules, so no workflow changes are needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JEizQuqZkmoSJf6saEPDH
The synctools library requires the desugar_jdk_libs_nio core-library
desugaring flavor (java.nio support), so :app:checkOseDebugAarMetadata failed
with the base desugar_jdk_libs variant. Switch to the _nio artifact (same
version 2.1.5, a superset), matching davx5-ose's own configuration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JEizQuqZkmoSJf6saEPDH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants