Skip to content

Feat: DataPatching: Map collection elements: Set/List elements. - #14252

Open
Pa-Touche wants to merge 2 commits into
developmentfrom
fix/exposures-fields
Open

Feat: DataPatching: Map collection elements: Set/List elements.#14252
Pa-Touche wants to merge 2 commits into
developmentfrom
fix/exposures-fields

Conversation

@Pa-Touche

@Pa-Touche Pa-Touche commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Supports all types supported by the ValueMapperRegistry.

Fixes #14251

Summary by CodeRabbit

  • New Features

    • Added support for patching collection fields such as lists and sets using comma-separated input.
    • Collection elements are now mapped into the correct target element type (including nested and inherited fields).
    • Added stronger validation to reject incompatible collection element types.
  • Tests

    • Expanded test coverage for collection mapping, type validation, nested paths, inherited fields, and exposure-related collection patching.

Supports all types supported by the ValueMapperRegistry.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aa5487b9-9c97-4623-9c72-a4a2d0afe35a

📥 Commits

Reviewing files that changed from the base of the PR and between 23852b9 and f14626b.

📒 Files selected for processing (2)
  • sormas-backend/src/main/java/de/symeda/sormas/backend/patch/mapping/ValueMapperRegistry.java
  • sormas-backend/src/test/java/de/symeda/sormas/backend/patch/mapping/ValueMapperRegistryTest.java

📝 Walkthrough

Walkthrough

Collection-valued patching now supports Set and List targets. Generic element types are inferred from fields, comma-separated values are mapped element-by-element, and already-typed collections undergo subtype validation. Tests cover reflection, mapper behavior, and exposure fields.

Changes

Collection patching

Layer / File(s) Summary
Collection contract and subtype propagation
sormas-api/.../ValuePatchRequest.java, sormas-backend/.../PropertyAccessor.java, sormas-backend/.../DataPatcherImpl.java
ValuePatchRequest carries collection subtype metadata, while DataPatcherImpl derives it from collection field generics, including nested and inherited fields.
Collection mapping and validation
sormas-backend/.../CollectionPatchMapper.java, sormas-backend/.../ValueMapperRegistry.java
Comma-separated strings are mapped into Set or List values, and already-typed collections are checked against their declared subtype.
Collection patch integration validation
sormas-backend/.../PropertyAccessorTest.java, sormas-backend/.../CollectionPatchMapperTest.java, sormas-backend/.../ValueMapperRegistryTest.java, sormas-backend/.../DataPatcherImplTest.java
Tests cover generic type resolution, mapper failures, subtype validation, and exposure collection patching.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DataPatcherImpl
  participant PropertyAccessor
  participant ValueMapperRegistry
  participant CollectionPatchMapper
  DataPatcherImpl->>PropertyAccessor: resolve collection element type
  DataPatcherImpl->>ValueMapperRegistry: submit collection patch request
  ValueMapperRegistry->>CollectionPatchMapper: map collection string
  CollectionPatchMapper->>ValueMapperRegistry: map each element
  ValueMapperRegistry-->>CollectionPatchMapper: return element result
  CollectionPatchMapper-->>DataPatcherImpl: return Set or List
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning AbstractBeanTest removes reference-data test support without any clear connection to collection-field patching. Remove the unrelated AbstractBeanTest cleanup or split it into a separate PR focused on that test infrastructure change.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding collection-element mapping for Set/List patches.
Description check ✅ Passed The description includes the required issue reference and a brief summary of the feature.
Linked Issues check ✅ Passed The PR implements the requested collection-field patching for Exposure fields using Set/List support and registry-backed element mapping.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/exposures-fields

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
sormas-api/src/main/java/de/symeda/sormas/api/patch/mapping/ValuePatchRequest.java (1)

22-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

collectionSubType typed as Class<T> is type-unsound; should be Class<?>.

collectionSubType represents the element type inside the collection identified by targetType, not the collection type itself, so it shouldn't share the same generic parameter T. With proper (non-raw) generics this wouldn't even compile — e.g. new ValuePatchRequest<Set>().setTargetType(Set.class).setCollectionSubType(ExposureSubSetting.class) fails because ExposureSubSetting.class is Class<ExposureSubSetting>, not Class<Set>.

This is why every consumer (DataPatcherImpl#valueMappingResult, CollectionPatchMapper#buildRequestFrom) and every new test is forced to use ValuePatchRequest as a raw type with @SuppressWarnings({"unchecked","rawtypes"}) — a direct symptom of this API's generics being unsound rather than a coincidence.

♻️ Proposed fix
-	`@Nullable`
-	private Class<T> collectionSubType;
+	`@Nullable`
+	private Class<?> collectionSubType;
-	`@Nullable`
-	public Class<T> getCollectionSubType() {
-		return collectionSubType;
-	}
-
-	public ValuePatchRequest<T> setCollectionSubType(`@Nullable` Class<T> collectionSubType) {
+	`@Nullable`
+	public Class<?> getCollectionSubType() {
+		return collectionSubType;
+	}
+
+	public ValuePatchRequest<T> setCollectionSubType(`@Nullable` Class<?> collectionSubType) {
		this.collectionSubType = collectionSubType;
		return this;
	}

Also applies to: 59-68

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@sormas-api/src/main/java/de/symeda/sormas/api/patch/mapping/ValuePatchRequest.java`
around lines 22 - 28, Change ValuePatchRequest.collectionSubType from Class<T>
to Class<?> because it represents the collection element type rather than the
request’s target type parameter. Update its getter, setter, and all consumers
including DataPatcherImpl#valueMappingResult and
CollectionPatchMapper#buildRequestFrom to use the corrected wildcard type, then
remove raw ValuePatchRequest usage and related unchecked/raw suppressions where
no longer needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/patch/mapping/ValueMapperRegistry.java`:
- Around line 59-68: Update the collection validation in ValueMapperRegistry to
evaluate every element with request.getCollectionSubType().isInstance rather
than sampling via findAny() or comparing exact classes. Preserve the existing
invalid-type result when any element is incompatible, while allowing empty
collections through the allMatch behavior.

---

Nitpick comments:
In
`@sormas-api/src/main/java/de/symeda/sormas/api/patch/mapping/ValuePatchRequest.java`:
- Around line 22-28: Change ValuePatchRequest.collectionSubType from Class<T> to
Class<?> because it represents the collection element type rather than the
request’s target type parameter. Update its getter, setter, and all consumers
including DataPatcherImpl#valueMappingResult and
CollectionPatchMapper#buildRequestFrom to use the corrected wildcard type, then
remove raw ValuePatchRequest usage and related unchecked/raw suppressions where
no longer needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b41c79b-ff9b-4508-a2c7-55d501bd4374

📥 Commits

Reviewing files that changed from the base of the PR and between b4607d9 and 23852b9.

📒 Files selected for processing (10)
  • sormas-api/src/main/java/de/symeda/sormas/api/patch/mapping/ValuePatchRequest.java
  • sormas-backend/src/main/java/de/symeda/sormas/backend/patch/DataPatcherImpl.java
  • sormas-backend/src/main/java/de/symeda/sormas/backend/patch/PropertyAccessor.java
  • sormas-backend/src/main/java/de/symeda/sormas/backend/patch/mapping/ValueMapperRegistry.java
  • sormas-backend/src/main/java/de/symeda/sormas/backend/patch/mapping/impl/valuemapper/CollectionPatchMapper.java
  • sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java
  • sormas-backend/src/test/java/de/symeda/sormas/backend/patch/PropertyAccessorTest.java
  • sormas-backend/src/test/java/de/symeda/sormas/backend/patch/mapping/ValueMapperRegistryTest.java
  • sormas-backend/src/test/java/de/symeda/sormas/backend/patch/mapping/impl/valuemapper/CollectionPatchMapperTest.java
  • sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java
💤 Files with no reviewable changes (1)
  • sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java

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.

Data Patching: Collection fields like Exposure.subSettings

1 participant