Skip to content

Commit 2c84d04

Browse files
cuzfrogfiliphr
authored andcommitted
#3240 Add Support for Java21 SequencedSet and SequencedMap
1 parent 668eeb5 commit 2c84d04

File tree

12 files changed

+164
-16
lines changed

12 files changed

+164
-16
lines changed

.github/workflows/main.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
java: [17, 21]
15+
java: [21]
1616
name: 'Linux JDK ${{ matrix.java }}'
1717
runs-on: ubuntu-latest
1818
steps:
@@ -24,31 +24,31 @@ jobs:
2424
distribution: 'zulu'
2525
java-version: ${{ matrix.java }}
2626
- name: 'Test'
27-
run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=${{ matrix.java != 17 }} install -DskipDistribution=${{ matrix.java != 17 }}
27+
run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=${{ matrix.java != 21 }} install -DskipDistribution=${{ matrix.java != 21 }}
2828
- name: 'Generate coverage report'
29-
if: matrix.java == 17
29+
if: matrix.java == 21
3030
run: ./mvnw jacoco:report
3131
- name: 'Upload coverage to Codecov'
32-
if: matrix.java == 17
32+
if: matrix.java == 21
3333
uses: codecov/codecov-action@v2
3434
- name: 'Publish Snapshots'
35-
if: matrix.java == 17 && github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'mapstruct/mapstruct'
35+
if: matrix.java == 21 && github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'mapstruct/mapstruct'
3636
run: ./mvnw -s etc/ci-settings.xml -DskipTests=true -DskipDistribution=true deploy
3737
integration_test_jdk:
3838
strategy:
3939
fail-fast: false
4040
matrix:
41-
java: [ 8, 11 ]
41+
java: [ 8, 11, 17 ]
4242
name: 'Linux JDK ${{ matrix.java }}'
4343
runs-on: ubuntu-latest
4444
steps:
4545
- name: 'Checkout'
4646
uses: actions/checkout@v4
47-
- name: 'Set up JDK 17 for building everything'
47+
- name: 'Set up JDK 21 for building everything'
4848
uses: actions/setup-java@v4
4949
with:
5050
distribution: 'zulu'
51-
java-version: 17
51+
java-version: 21
5252
- name: 'Install Processor'
5353
run: ./mvnw ${MAVEN_ARGS} -DskipTests install -pl processor -am
5454
- name: 'Set up JDK ${{ matrix.java }} for running integration tests'
@@ -63,22 +63,22 @@ jobs:
6363
runs-on: windows-latest
6464
steps:
6565
- uses: actions/checkout@v4
66-
- name: 'Set up JDK 17'
66+
- name: 'Set up JDK 21'
6767
uses: actions/setup-java@v4
6868
with:
6969
distribution: 'zulu'
70-
java-version: 17
70+
java-version: 21
7171
- name: 'Test'
7272
run: ./mvnw %MAVEN_ARGS% install
7373
mac:
7474
name: 'Mac OS'
7575
runs-on: macos-latest
7676
steps:
7777
- uses: actions/checkout@v3
78-
- name: 'Set up JDK 17'
78+
- name: 'Set up JDK 21'
7979
uses: actions/setup-java@v4
8080
with:
8181
distribution: 'zulu'
82-
java-version: 17
82+
java-version: 21
8383
- name: 'Test'
8484
run: ./mvnw ${MAVEN_ARGS} install

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Setup Java
2323
uses: actions/setup-java@v4
2424
with:
25-
java-version: 17
25+
java-version: 21
2626
distribution: 'zulu'
2727
cache: maven
2828

documentation/src/main/asciidoc/chapter-6-mapping-collections.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,16 @@ When an iterable or map mapping method declares an interface type as return type
212212

213213
|`Set`|`LinkedHashSet`
214214

215+
|`SequencedSet`|`LinkedHashSet`
216+
215217
|`SortedSet`|`TreeSet`
216218

217219
|`NavigableSet`|`TreeSet`
218220

219221
|`Map`|`LinkedHashMap`
220222

223+
|`SequencedMap`|`LinkedHashMap`
224+
221225
|`SortedMap`|`TreeMap`
222226

223227
|`NavigableMap`|`TreeMap`

integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationExclusionCliEnhancer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public Collection<String> getAdditionalCommandLineArguments(ProcessorTest.Proces
3434
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" );
3535
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" );
3636
additionalExcludes.add( "org/mapstruct/ap/test/annotatewith/deprecated/jdk11/*.java" );
37+
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
3738
if ( processorType == ProcessorTest.ProcessorType.ECLIPSE_JDT ) {
3839
additionalExcludes.add(
3940
"org/mapstruct/ap/test/selection/methodgenerics/wildcards/LifecycleIntersectionMapper.java" );
@@ -42,9 +43,15 @@ public Collection<String> getAdditionalCommandLineArguments(ProcessorTest.Proces
4243
case JAVA_9:
4344
// TODO find out why this fails:
4445
additionalExcludes.add( "org/mapstruct/ap/test/collection/wildcard/BeanMapper.java" );
46+
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
4547
break;
4648
case JAVA_11:
4749
additionalExcludes.add( "org/mapstruct/ap/test/**/spring/**/*.java" );
50+
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
51+
break;
52+
case JAVA_17:
53+
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
54+
break;
4855
default:
4956
}
5057

integrationtest/src/test/resources/fullFeatureTest/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
<exclude>${additionalExclude9}</exclude>
6060
<exclude>${additionalExclude10}</exclude>
6161
<exclude>${additionalExclude11}</exclude>
62+
<exclude>${additionalExclude12}</exclude>
63+
<exclude>${additionalExclude13}</exclude>
6264
</excludes>
6365
</configuration>
6466
</plugin>

parent/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
4848
<!--
4949
The minimum Java Version that is needed to build a module in MapStruct.
50-
The processor module needs at least Java 17.
50+
The processor module needs at least Java 21.
5151
-->
5252
<minimum.java.version>1.8</minimum.java.version>
5353
<protobuf.version>3.25.5</protobuf.version>

processor/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<!-- Netbeans has a problem when we use late binding with @ in the surefire arg line.
2525
Therefore we set this empty property here-->
2626
<jacocoArgLine />
27-
<minimum.java.version>17</minimum.java.version>
27+
<minimum.java.version>21</minimum.java.version>
2828
</properties>
2929

3030
<dependencies>

processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.mapstruct.ap.internal.util.ElementUtils;
4646
import org.mapstruct.ap.internal.util.Extractor;
4747
import org.mapstruct.ap.internal.util.FormattingMessager;
48+
import org.mapstruct.ap.internal.util.JavaCollectionConstants;
4849
import org.mapstruct.ap.internal.util.JavaStreamConstants;
4950
import org.mapstruct.ap.internal.util.Message;
5051
import org.mapstruct.ap.internal.util.NativeTypes;
@@ -149,6 +150,18 @@ public TypeFactory(ElementUtils elementUtils, TypeUtils typeUtils, FormattingMes
149150
ConcurrentNavigableMap.class.getName(),
150151
withDefaultConstructor( getType( ConcurrentSkipListMap.class ) )
151152
);
153+
implementationTypes.put(
154+
JavaCollectionConstants.SEQUENCED_SET_FQN,
155+
sourceVersionAtLeast19 ?
156+
withFactoryMethod( getType( LinkedHashSet.class ), LINKED_HASH_SET_FACTORY_METHOD_NAME ) :
157+
withLoadFactorAdjustment( getType( LinkedHashSet.class ) )
158+
);
159+
implementationTypes.put(
160+
JavaCollectionConstants.SEQUENCED_MAP_FQN,
161+
sourceVersionAtLeast19 ?
162+
withFactoryMethod( getType( LinkedHashMap.class ), LINKED_HASH_MAP_FACTORY_METHOD_NAME ) :
163+
withLoadFactorAdjustment( getType( LinkedHashMap.class ) )
164+
);
152165

153166
this.loggingVerbose = loggingVerbose;
154167
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.ap.internal.util;
7+
8+
/**
9+
* Helper holding Java collections full qualified class names for conversion registration,
10+
* to achieve Java compatibility.
11+
*
12+
* @author Cause Chung
13+
*/
14+
public final class JavaCollectionConstants {
15+
public static final String SEQUENCED_MAP_FQN = "java.util.SequencedMap";
16+
public static final String SEQUENCED_SET_FQN = "java.util.SequencedSet";
17+
18+
private JavaCollectionConstants() {
19+
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.ap.test.collection.defaultimplementation.jdk21;
7+
8+
import java.util.Arrays;
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.SequencedMap;
13+
import java.util.SequencedSet;
14+
15+
import org.mapstruct.ap.test.collection.defaultimplementation.Source;
16+
import org.mapstruct.ap.test.collection.defaultimplementation.SourceFoo;
17+
import org.mapstruct.ap.test.collection.defaultimplementation.Target;
18+
import org.mapstruct.ap.test.collection.defaultimplementation.TargetFoo;
19+
import org.mapstruct.ap.testutil.IssueKey;
20+
import org.mapstruct.ap.testutil.ProcessorTest;
21+
import org.mapstruct.ap.testutil.WithClasses;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
import static org.assertj.core.api.Assertions.entry;
25+
26+
@WithClasses({
27+
Source.class,
28+
Target.class,
29+
SourceFoo.class,
30+
TargetFoo.class,
31+
SequencedCollectionsMapper.class
32+
})
33+
@IssueKey("3420")
34+
class SequencedCollectionsDefaultImplementationTest {
35+
36+
@ProcessorTest
37+
public void shouldUseDefaultImplementationForSequencedMap() {
38+
SequencedMap<String, TargetFoo> target =
39+
SequencedCollectionsMapper.INSTANCE.sourceFooMapToTargetFooSequencedMap( createSourceFooMap() );
40+
41+
assertResultMap( target );
42+
}
43+
44+
@ProcessorTest
45+
public void shouldUseDefaultImplementationForSequencedSet() {
46+
SequencedSet<TargetFoo> target =
47+
SequencedCollectionsMapper.INSTANCE.sourceFoosToTargetFooSequencedSet( createSourceFooList() );
48+
49+
assertResultList( target );
50+
}
51+
52+
private void assertResultList(Iterable<TargetFoo> fooIterable) {
53+
assertThat( fooIterable ).isNotNull();
54+
assertThat( fooIterable ).containsOnly( new TargetFoo( "Bob" ), new TargetFoo( "Alice" ) );
55+
}
56+
57+
private void assertResultMap(Map<String, TargetFoo> result) {
58+
assertThat( result ).isNotNull();
59+
assertThat( result ).hasSize( 2 );
60+
assertThat( result ).contains( entry( "1", new TargetFoo( "Bob" ) ), entry( "2", new TargetFoo( "Alice" ) ) );
61+
}
62+
63+
private Map<Long, SourceFoo> createSourceFooMap() {
64+
Map<Long, SourceFoo> map = new HashMap<>();
65+
map.put( 1L, new SourceFoo( "Bob" ) );
66+
map.put( 2L, new SourceFoo( "Alice" ) );
67+
68+
return map;
69+
}
70+
71+
private List<SourceFoo> createSourceFooList() {
72+
return Arrays.asList( new SourceFoo( "Bob" ), new SourceFoo( "Alice" ) );
73+
}
74+
}

0 commit comments

Comments
 (0)