Repository navigation
feat: auto-detect generated builders in MapStruct via BuilderProvider SPI (#300) #312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
igel-devin-ai
wants to merge
25
commits into
java-helpers:main
Choose a base branch
from
igel-devin-ai:devin/1790806270-mapstruct-builder-provider
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
6368cee
Add MapStruct BuilderProvider for generated builders
devin-ai-integration[bot] 6515416
Hide generated helper methods from MapStruct bean mapping
devin-ai-integration[bot] 37aae7b
Rename MapStruct SPI classes to carry the framework name
devin-ai-integration[bot] e4dbd44
Add usingMapStructIntegration opt-out for the MapStruct SPIs
devin-ai-integration[bot] 6d373c0
Reduce per-bean work in the MapStruct SPI lookups
devin-ai-integration[bot] 50a258b
Wire usingMapStructIntegration through BuilderProcessor and share pla…
devin-ai-integration[bot] 854a62a
Claim only builders this generator emitted
devin-ai-integration[bot] 01c11fb
Claim builders exclusively through the published registry
devin-ai-integration[bot] 4da0050
Guard shared state with a per-compilation lifecycle
devin-ai-integration[bot] 8a28134
Rename MapStructIntegration to SpiIntegration in processing
devin-ai-integration[bot] c278bbf
Rename SpiIntegration to SimpleBuildersSpiIntegration
devin-ai-integration[bot] 588e013
Publish resolved builders so SPIs read the registry, not elements
devin-ai-integration[bot] b6fb24a
Resolve MapStruct SPI review round 2 and add in-javac probe test
devin-ai-integration[bot] 4fd7246
Bound SPI deferral by lifecycle state instead of marker alone
devin-ai-integration[bot] 9b3e449
MapStruct SPI: marked-only deferral, analyser helpers, test cleanup
devin-ai-integration[bot] 6feebfe
Pin SPI state to its compilation via Elements identity
devin-ai-integration[bot] 38de9b9
Fix Sonar findings: AtomicReference, logger, NPE guard
devin-ai-integration[bot] 0845b87
Defer marked beans in every non-final state
devin-ai-integration[bot] 50c3d03
Drop TARGETS_REGISTERED — keep INIT/PROCESSING/FINISHED
devin-ai-integration[bot] 111c006
Generate builders in exactly one round and defer all misses until the…
devin-ai-integration[bot] 071e71e
Gate the generating round on the finished state and document the neve…
devin-ai-integration[bot] 252d607
Read the integration switch from the SPI options, flatten PublishedBu…
devin-ai-integration[bot] e01ec66
Read the integration switch on the SPI side and bake staleness into t…
devin-ai-integration[bot] 3cc0114
Scope every SPI lookup to the caller's compilation
devin-ai-integration[bot] a5a4014
Review cleanup: drop redundant findFields, stale docs and javadoc
devin-ai-integration[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...enerated-example-builder/org/javahelpers/simple/builders/example/PersonDtoMapperImpl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package org.javahelpers.simple.builders.example; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import javax.annotation.processing.Generated; | ||
|
|
||
| @Generated( | ||
| value = "org.mapstruct.ap.MappingProcessor" | ||
| ) | ||
| public class PersonDtoMapperImpl implements PersonDtoMapper { | ||
|
|
||
| @Override | ||
| public PersonDto copy(PersonDto source) { | ||
| if ( source == null ) { | ||
| return null; | ||
| } | ||
|
|
||
| PersonDtoBuilder personDto = PersonDtoBuilder.create(); | ||
|
|
||
| personDto.birthdate( source.getBirthdate() ); | ||
| personDto.mannschaft( source.getMannschaft() ); | ||
| personDto.name( source.getName() ); | ||
| List<String> list = source.getNickNames(); | ||
| if ( list != null ) { | ||
| personDto.nickNames( new ArrayList<String>( list ) ); | ||
| } | ||
|
|
||
| return personDto.build(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
example/src/main/java/org/javahelpers/simple/builders/example/PersonDtoMapper.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| /* | ||
| * MIT License | ||
| * | ||
| * Copyright (c) 2026 Andreas Igel | ||
| * | ||
| * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| * of this software and associated documentation files (the "Software"), to deal | ||
| * in the Software without restriction, including without limitation the rights | ||
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| * copies of the Software, and to permit persons with the following conditions: | ||
| * | ||
| * The above copyright notice and this permission notice shall be included in all | ||
| * copies or substantial portions of the Software. | ||
| * | ||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| * SOFTWARE. | ||
| */ | ||
|
|
||
| package org.javahelpers.simple.builders.example; | ||
|
|
||
| import org.mapstruct.Mapper; | ||
|
|
||
| /** Maps {@link PersonDto} using the generated {@code PersonDtoBuilder} discovered by MapStruct. */ | ||
| @Mapper | ||
| public interface PersonDtoMapper { | ||
|
|
||
| PersonDto copy(PersonDto source); | ||
| } |
77 changes: 77 additions & 0 deletions
77
example/src/test/java/org/javahelpers/simple/builders/example/MapStructIntegrationTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /* | ||
| * MIT License | ||
| * | ||
| * Copyright (c) 2026 Andreas Igel | ||
| * | ||
| * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| * of this software and associated documentation files (the "Software"), to deal | ||
| * in the Software without restriction, including without limitation the rights | ||
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| * copies of the Software, and to permit persons with the following conditions: | ||
| * | ||
| * The above copyright notice and this permission notice shall be included in all | ||
| * copies or substantial portions of the Software. | ||
| * | ||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| * SOFTWARE. | ||
| */ | ||
|
|
||
| package org.javahelpers.simple.builders.example; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.time.LocalDate; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.mapstruct.factory.Mappers; | ||
|
|
||
| /** | ||
| * Verifies that MapStruct discovers and uses the generated {@code PersonDtoBuilder} through the | ||
| * {@code MapStructBuilderProvider} SPI shipped in simple-builders-processor. | ||
| */ | ||
| class MapStructIntegrationTest { | ||
|
|
||
| private static final Path GENERATED_MAPPER_IMPL = | ||
| Path.of( | ||
| "generated-example-builder", | ||
| "org", | ||
| "javahelpers", | ||
| "simple", | ||
| "builders", | ||
| "example", | ||
| "PersonDtoMapperImpl.java"); | ||
|
|
||
| @Test | ||
| void shouldMapPersonDtoUsingGeneratedBuilder() { | ||
| PersonDto source = PersonDtoBuilder.create() | ||
| .name("Alice") | ||
| .birthdate(LocalDate.of(1990, 1, 1)) | ||
| .build(); | ||
|
|
||
| PersonDto copy = Mappers.getMapper(PersonDtoMapper.class).copy(source); | ||
|
|
||
| assertNotNull(copy); | ||
| assertEquals("Alice", copy.getName()); | ||
| assertEquals(LocalDate.of(1990, 1, 1), copy.getBirthdate()); | ||
| } | ||
|
|
||
| @Test | ||
| void shouldGenerateMapperUsingPersonDtoBuilder() throws IOException { | ||
| String mapperImpl = Files.readString(GENERATED_MAPPER_IMPL); | ||
| assertTrue( | ||
| mapperImpl.contains("PersonDtoBuilder.create()"), | ||
| "MapStruct mapper implementation should use PersonDtoBuilder.create()"); | ||
| assertTrue( | ||
| mapperImpl.contains(".build()"), | ||
| "MapStruct mapper implementation should finish via build()"); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.