mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#3240 Add Support for Java21 SequencedSet and SequencedMap
This commit is contained in:
parent
668eeb5de1
commit
2c84d04463
24
.github/workflows/main.yml
vendored
24
.github/workflows/main.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
java: [17, 21]
|
java: [21]
|
||||||
name: 'Linux JDK ${{ matrix.java }}'
|
name: 'Linux JDK ${{ matrix.java }}'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@ -24,31 +24,31 @@ jobs:
|
|||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
- name: 'Test'
|
- name: 'Test'
|
||||||
run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=${{ matrix.java != 17 }} install -DskipDistribution=${{ matrix.java != 17 }}
|
run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=${{ matrix.java != 21 }} install -DskipDistribution=${{ matrix.java != 21 }}
|
||||||
- name: 'Generate coverage report'
|
- name: 'Generate coverage report'
|
||||||
if: matrix.java == 17
|
if: matrix.java == 21
|
||||||
run: ./mvnw jacoco:report
|
run: ./mvnw jacoco:report
|
||||||
- name: 'Upload coverage to Codecov'
|
- name: 'Upload coverage to Codecov'
|
||||||
if: matrix.java == 17
|
if: matrix.java == 21
|
||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
- name: 'Publish Snapshots'
|
- name: 'Publish Snapshots'
|
||||||
if: matrix.java == 17 && github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'mapstruct/mapstruct'
|
if: matrix.java == 21 && github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'mapstruct/mapstruct'
|
||||||
run: ./mvnw -s etc/ci-settings.xml -DskipTests=true -DskipDistribution=true deploy
|
run: ./mvnw -s etc/ci-settings.xml -DskipTests=true -DskipDistribution=true deploy
|
||||||
integration_test_jdk:
|
integration_test_jdk:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
java: [ 8, 11 ]
|
java: [ 8, 11, 17 ]
|
||||||
name: 'Linux JDK ${{ matrix.java }}'
|
name: 'Linux JDK ${{ matrix.java }}'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout'
|
- name: 'Checkout'
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: 'Set up JDK 17 for building everything'
|
- name: 'Set up JDK 21 for building everything'
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: 'Install Processor'
|
- name: 'Install Processor'
|
||||||
run: ./mvnw ${MAVEN_ARGS} -DskipTests install -pl processor -am
|
run: ./mvnw ${MAVEN_ARGS} -DskipTests install -pl processor -am
|
||||||
- name: 'Set up JDK ${{ matrix.java }} for running integration tests'
|
- name: 'Set up JDK ${{ matrix.java }} for running integration tests'
|
||||||
@ -63,11 +63,11 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: 'Set up JDK 17'
|
- name: 'Set up JDK 21'
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: 'Test'
|
- name: 'Test'
|
||||||
run: ./mvnw %MAVEN_ARGS% install
|
run: ./mvnw %MAVEN_ARGS% install
|
||||||
mac:
|
mac:
|
||||||
@ -75,10 +75,10 @@ jobs:
|
|||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: 'Set up JDK 17'
|
- name: 'Set up JDK 21'
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: 'Test'
|
- name: 'Test'
|
||||||
run: ./mvnw ${MAVEN_ARGS} install
|
run: ./mvnw ${MAVEN_ARGS} install
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: 17
|
java-version: 21
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: maven
|
cache: maven
|
||||||
|
|
||||||
|
@ -212,12 +212,16 @@ When an iterable or map mapping method declares an interface type as return type
|
|||||||
|
|
||||||
|`Set`|`LinkedHashSet`
|
|`Set`|`LinkedHashSet`
|
||||||
|
|
||||||
|
|`SequencedSet`|`LinkedHashSet`
|
||||||
|
|
||||||
|`SortedSet`|`TreeSet`
|
|`SortedSet`|`TreeSet`
|
||||||
|
|
||||||
|`NavigableSet`|`TreeSet`
|
|`NavigableSet`|`TreeSet`
|
||||||
|
|
||||||
|`Map`|`LinkedHashMap`
|
|`Map`|`LinkedHashMap`
|
||||||
|
|
||||||
|
|`SequencedMap`|`LinkedHashMap`
|
||||||
|
|
||||||
|`SortedMap`|`TreeMap`
|
|`SortedMap`|`TreeMap`
|
||||||
|
|
||||||
|`NavigableMap`|`TreeMap`
|
|`NavigableMap`|`TreeMap`
|
||||||
|
@ -34,6 +34,7 @@ public final class FullFeatureCompilationExclusionCliEnhancer implements Process
|
|||||||
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" );
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" );
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/annotatewith/deprecated/jdk11/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/annotatewith/deprecated/jdk11/*.java" );
|
||||||
|
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
|
||||||
if ( processorType == ProcessorTest.ProcessorType.ECLIPSE_JDT ) {
|
if ( processorType == ProcessorTest.ProcessorType.ECLIPSE_JDT ) {
|
||||||
additionalExcludes.add(
|
additionalExcludes.add(
|
||||||
"org/mapstruct/ap/test/selection/methodgenerics/wildcards/LifecycleIntersectionMapper.java" );
|
"org/mapstruct/ap/test/selection/methodgenerics/wildcards/LifecycleIntersectionMapper.java" );
|
||||||
@ -42,9 +43,15 @@ public final class FullFeatureCompilationExclusionCliEnhancer implements Process
|
|||||||
case JAVA_9:
|
case JAVA_9:
|
||||||
// TODO find out why this fails:
|
// TODO find out why this fails:
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/collection/wildcard/BeanMapper.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/collection/wildcard/BeanMapper.java" );
|
||||||
|
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
|
||||||
break;
|
break;
|
||||||
case JAVA_11:
|
case JAVA_11:
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/**/spring/**/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/**/spring/**/*.java" );
|
||||||
|
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
|
||||||
|
break;
|
||||||
|
case JAVA_17:
|
||||||
|
additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
<exclude>${additionalExclude9}</exclude>
|
<exclude>${additionalExclude9}</exclude>
|
||||||
<exclude>${additionalExclude10}</exclude>
|
<exclude>${additionalExclude10}</exclude>
|
||||||
<exclude>${additionalExclude11}</exclude>
|
<exclude>${additionalExclude11}</exclude>
|
||||||
|
<exclude>${additionalExclude12}</exclude>
|
||||||
|
<exclude>${additionalExclude13}</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
|
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
|
||||||
<!--
|
<!--
|
||||||
The minimum Java Version that is needed to build a module in MapStruct.
|
The minimum Java Version that is needed to build a module in MapStruct.
|
||||||
The processor module needs at least Java 17.
|
The processor module needs at least Java 21.
|
||||||
-->
|
-->
|
||||||
<minimum.java.version>1.8</minimum.java.version>
|
<minimum.java.version>1.8</minimum.java.version>
|
||||||
<protobuf.version>3.25.5</protobuf.version>
|
<protobuf.version>3.25.5</protobuf.version>
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<!-- Netbeans has a problem when we use late binding with @ in the surefire arg line.
|
<!-- Netbeans has a problem when we use late binding with @ in the surefire arg line.
|
||||||
Therefore we set this empty property here-->
|
Therefore we set this empty property here-->
|
||||||
<jacocoArgLine />
|
<jacocoArgLine />
|
||||||
<minimum.java.version>17</minimum.java.version>
|
<minimum.java.version>21</minimum.java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -45,6 +45,7 @@ import org.mapstruct.ap.internal.util.Collections;
|
|||||||
import org.mapstruct.ap.internal.util.ElementUtils;
|
import org.mapstruct.ap.internal.util.ElementUtils;
|
||||||
import org.mapstruct.ap.internal.util.Extractor;
|
import org.mapstruct.ap.internal.util.Extractor;
|
||||||
import org.mapstruct.ap.internal.util.FormattingMessager;
|
import org.mapstruct.ap.internal.util.FormattingMessager;
|
||||||
|
import org.mapstruct.ap.internal.util.JavaCollectionConstants;
|
||||||
import org.mapstruct.ap.internal.util.JavaStreamConstants;
|
import org.mapstruct.ap.internal.util.JavaStreamConstants;
|
||||||
import org.mapstruct.ap.internal.util.Message;
|
import org.mapstruct.ap.internal.util.Message;
|
||||||
import org.mapstruct.ap.internal.util.NativeTypes;
|
import org.mapstruct.ap.internal.util.NativeTypes;
|
||||||
@ -149,6 +150,18 @@ public class TypeFactory {
|
|||||||
ConcurrentNavigableMap.class.getName(),
|
ConcurrentNavigableMap.class.getName(),
|
||||||
withDefaultConstructor( getType( ConcurrentSkipListMap.class ) )
|
withDefaultConstructor( getType( ConcurrentSkipListMap.class ) )
|
||||||
);
|
);
|
||||||
|
implementationTypes.put(
|
||||||
|
JavaCollectionConstants.SEQUENCED_SET_FQN,
|
||||||
|
sourceVersionAtLeast19 ?
|
||||||
|
withFactoryMethod( getType( LinkedHashSet.class ), LINKED_HASH_SET_FACTORY_METHOD_NAME ) :
|
||||||
|
withLoadFactorAdjustment( getType( LinkedHashSet.class ) )
|
||||||
|
);
|
||||||
|
implementationTypes.put(
|
||||||
|
JavaCollectionConstants.SEQUENCED_MAP_FQN,
|
||||||
|
sourceVersionAtLeast19 ?
|
||||||
|
withFactoryMethod( getType( LinkedHashMap.class ), LINKED_HASH_MAP_FACTORY_METHOD_NAME ) :
|
||||||
|
withLoadFactorAdjustment( getType( LinkedHashMap.class ) )
|
||||||
|
);
|
||||||
|
|
||||||
this.loggingVerbose = loggingVerbose;
|
this.loggingVerbose = loggingVerbose;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.internal.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper holding Java collections full qualified class names for conversion registration,
|
||||||
|
* to achieve Java compatibility.
|
||||||
|
*
|
||||||
|
* @author Cause Chung
|
||||||
|
*/
|
||||||
|
public final class JavaCollectionConstants {
|
||||||
|
public static final String SEQUENCED_MAP_FQN = "java.util.SequencedMap";
|
||||||
|
public static final String SEQUENCED_SET_FQN = "java.util.SequencedSet";
|
||||||
|
|
||||||
|
private JavaCollectionConstants() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.defaultimplementation.jdk21;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.SequencedMap;
|
||||||
|
import java.util.SequencedSet;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.Source;
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.SourceFoo;
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.Target;
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.TargetFoo;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.ProcessorTest;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
|
||||||
|
@WithClasses({
|
||||||
|
Source.class,
|
||||||
|
Target.class,
|
||||||
|
SourceFoo.class,
|
||||||
|
TargetFoo.class,
|
||||||
|
SequencedCollectionsMapper.class
|
||||||
|
})
|
||||||
|
@IssueKey("3420")
|
||||||
|
class SequencedCollectionsDefaultImplementationTest {
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldUseDefaultImplementationForSequencedMap() {
|
||||||
|
SequencedMap<String, TargetFoo> target =
|
||||||
|
SequencedCollectionsMapper.INSTANCE.sourceFooMapToTargetFooSequencedMap( createSourceFooMap() );
|
||||||
|
|
||||||
|
assertResultMap( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void shouldUseDefaultImplementationForSequencedSet() {
|
||||||
|
SequencedSet<TargetFoo> target =
|
||||||
|
SequencedCollectionsMapper.INSTANCE.sourceFoosToTargetFooSequencedSet( createSourceFooList() );
|
||||||
|
|
||||||
|
assertResultList( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertResultList(Iterable<TargetFoo> fooIterable) {
|
||||||
|
assertThat( fooIterable ).isNotNull();
|
||||||
|
assertThat( fooIterable ).containsOnly( new TargetFoo( "Bob" ), new TargetFoo( "Alice" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertResultMap(Map<String, TargetFoo> result) {
|
||||||
|
assertThat( result ).isNotNull();
|
||||||
|
assertThat( result ).hasSize( 2 );
|
||||||
|
assertThat( result ).contains( entry( "1", new TargetFoo( "Bob" ) ), entry( "2", new TargetFoo( "Alice" ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Long, SourceFoo> createSourceFooMap() {
|
||||||
|
Map<Long, SourceFoo> map = new HashMap<>();
|
||||||
|
map.put( 1L, new SourceFoo( "Bob" ) );
|
||||||
|
map.put( 2L, new SourceFoo( "Alice" ) );
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SourceFoo> createSourceFooList() {
|
||||||
|
return Arrays.asList( new SourceFoo( "Bob" ), new SourceFoo( "Alice" ) );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.defaultimplementation.jdk21;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.SequencedMap;
|
||||||
|
import java.util.SequencedSet;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.SourceFoo;
|
||||||
|
import org.mapstruct.ap.test.collection.defaultimplementation.TargetFoo;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SequencedCollectionsMapper {
|
||||||
|
|
||||||
|
SequencedCollectionsMapper INSTANCE = Mappers.getMapper( SequencedCollectionsMapper.class );
|
||||||
|
|
||||||
|
SequencedSet<TargetFoo> sourceFoosToTargetFooSequencedSet(Collection<SourceFoo> foos);
|
||||||
|
|
||||||
|
SequencedMap<String, TargetFoo> sourceFooMapToTargetFooSequencedMap(Map<Long, SourceFoo> foos);
|
||||||
|
}
|
@ -130,7 +130,8 @@ To learn more about MapStruct, refer to the [project homepage](https://mapstruct
|
|||||||
|
|
||||||
## Building from Source
|
## Building from Source
|
||||||
|
|
||||||
MapStruct uses Maven for its build. Java 17 is required for building MapStruct from source. To build the complete project, run
|
MapStruct uses Maven for its build. Java 21 is required for building MapStruct from source.
|
||||||
|
To build the complete project, run
|
||||||
|
|
||||||
./mvnw clean install
|
./mvnw clean install
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user