mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#2014 Add support for mapping from Java 14 records
This commit is contained in:
parent
273487f152
commit
f5771c4177
@ -14,6 +14,9 @@ matrix:
|
||||
- jdk: openjdk13
|
||||
# There is an issue with the documentation so skip it
|
||||
script: mvn -B -V clean install -DskipDistribution=true
|
||||
- jdk: openjdk14
|
||||
# There is an issue with the documentation so skip it
|
||||
script: mvn -B -V clean install -DskipDistribution=true
|
||||
# There is an issue with the documentation so skip it
|
||||
- jdk: openjdk-ea
|
||||
script: mvn -B -V clean install -DskipDistribution=true
|
||||
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
package org.mapstruct.itest.tests;
|
||||
|
||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.parallel.Execution;
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode;
|
||||
import org.mapstruct.itest.testutil.extension.ProcessorTest;
|
||||
@ -99,6 +101,13 @@ public class MavenIntegrationTest {
|
||||
void protobufBuilderTest() {
|
||||
}
|
||||
|
||||
@ProcessorTest(baseDir = "recordsTest", processorTypes = {
|
||||
ProcessorTest.ProcessorType.JAVAC
|
||||
})
|
||||
@EnabledForJreRange(min = JRE.JAVA_14)
|
||||
void recordsTest() {
|
||||
}
|
||||
|
||||
@ProcessorTest(baseDir = "simpleTest")
|
||||
void simpleTest() {
|
||||
}
|
||||
|
102
integrationtest/src/test/resources/recordsTest/pom.xml
Normal file
102
integrationtest/src/test/resources/recordsTest/pom.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright MapStruct Authors.
|
||||
|
||||
Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-it-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>recordsTest</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>generate-via-compiler-plugin</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerArgument
|
||||
combine.self="override"></compilerArgument>
|
||||
<compilerId>\${compiler-id}</compilerId>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
<artifactId>tycho-compiler-jdt</artifactId>
|
||||
<version>${org.eclipse.tycho.compiler-jdt.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>debug-forked-javac</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<configuration>
|
||||
<fork>true</fork>
|
||||
<compilerArgs>
|
||||
<arg>--enable-preview</arg>
|
||||
<arg>-J-Xdebug</arg>
|
||||
<arg>-J-Xnoagent</arg>
|
||||
<arg>-J-Djava.compiler=NONE</arg>
|
||||
<arg>-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<argLine>--enable-preview</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.itest.records;
|
||||
|
||||
/**
|
||||
* @author Filip Hrisafov
|
||||
*/
|
||||
public record CustomerDto(String name, String email) {
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.itest.records;
|
||||
|
||||
/**
|
||||
* @author Filip Hrisafov
|
||||
*/
|
||||
public class CustomerEntity {
|
||||
|
||||
private String name;
|
||||
private String mail;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getMail() {
|
||||
return mail;
|
||||
}
|
||||
|
||||
public void setMail(String mail) {
|
||||
this.mail = mail;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.itest.records;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Filip Hrisafov
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustomerMapper {
|
||||
|
||||
CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class );
|
||||
|
||||
@Mapping(target = "mail", source = "email")
|
||||
CustomerEntity fromRecord(CustomerDto record);
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.itest.records;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mapstruct.itest.records.CustomerDto;
|
||||
import org.mapstruct.itest.records.CustomerEntity;
|
||||
import org.mapstruct.itest.records.CustomerMapper;
|
||||
|
||||
public class RecordsTest {
|
||||
|
||||
@Test
|
||||
public void shouldMapRecord() {
|
||||
CustomerEntity customer = CustomerMapper.INSTANCE.fromRecord( new CustomerDto( "Kermit", "kermit@test.com" ) );
|
||||
|
||||
assertThat( customer ).isNotNull();
|
||||
assertThat( customer.getName() ).isEqualTo( "Kermit" );
|
||||
assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" );
|
||||
}
|
||||
}
|
@ -510,7 +510,7 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jvnet.jaxb2.maven2</groupId>
|
||||
|
@ -498,6 +498,11 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Accessor> recordAccessors = filters.recordsIn( typeElement );
|
||||
for ( Map.Entry<String, Accessor> recordEntry : recordAccessors.entrySet() ) {
|
||||
modifiableGetters.putIfAbsent( recordEntry.getKey(), recordEntry.getValue() );
|
||||
}
|
||||
|
||||
List<Accessor> fieldsList = filters.fieldsIn( getAllFields() );
|
||||
for ( Accessor field : fieldsList ) {
|
||||
String propertyName = getPropertyName( field );
|
||||
|
@ -5,11 +5,16 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.ExecutableType;
|
||||
@ -30,9 +35,29 @@ import static org.mapstruct.ap.internal.util.accessor.AccessorType.SETTER;
|
||||
* Filter methods for working with {@link Element} collections.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
* @author Filip Hrisafov
|
||||
*/
|
||||
public class Filters {
|
||||
|
||||
private static final Method RECORD_COMPONENTS_METHOD;
|
||||
private static final Method RECORD_COMPONENT_ACCESSOR_METHOD;
|
||||
|
||||
static {
|
||||
Method recordComponentsMethod;
|
||||
Method recordComponentAccessorMethod;
|
||||
try {
|
||||
recordComponentsMethod = TypeElement.class.getMethod( "getRecordComponents" );
|
||||
recordComponentAccessorMethod = Class.forName( "javax.lang.model.element.RecordComponentElement" )
|
||||
.getMethod( "getAccessor" );
|
||||
}
|
||||
catch ( NoSuchMethodException | ClassNotFoundException e ) {
|
||||
recordComponentsMethod = null;
|
||||
recordComponentAccessorMethod = null;
|
||||
}
|
||||
RECORD_COMPONENTS_METHOD = recordComponentsMethod;
|
||||
RECORD_COMPONENT_ACCESSOR_METHOD = recordComponentAccessorMethod;
|
||||
}
|
||||
|
||||
private final AccessorNamingUtils accessorNaming;
|
||||
private final Types typeUtils;
|
||||
private final TypeMirror typeMirror;
|
||||
@ -50,6 +75,33 @@ public class Filters {
|
||||
.collect( Collectors.toCollection( LinkedList::new ) );
|
||||
}
|
||||
|
||||
public Map<String, Accessor> recordsIn(TypeElement typeElement) {
|
||||
if ( RECORD_COMPONENTS_METHOD == null || RECORD_COMPONENT_ACCESSOR_METHOD == null ) {
|
||||
return java.util.Collections.emptyMap();
|
||||
}
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Element> recordComponents = (List<Element>) RECORD_COMPONENTS_METHOD.invoke( typeElement );
|
||||
Map<String, Accessor> recordAccessors = new LinkedHashMap<>();
|
||||
for ( Element recordComponent : recordComponents ) {
|
||||
ExecutableElement recordExecutableElement =
|
||||
(ExecutableElement) RECORD_COMPONENT_ACCESSOR_METHOD.invoke( recordComponent );
|
||||
recordAccessors.put(
|
||||
recordComponent.getSimpleName().toString(),
|
||||
new ExecutableElementAccessor( recordExecutableElement,
|
||||
getReturnType( recordExecutableElement ),
|
||||
GETTER
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return recordAccessors;
|
||||
}
|
||||
catch ( IllegalAccessException | InvocationTargetException e ) {
|
||||
return java.util.Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
private TypeMirror getReturnType(ExecutableElement executableElement) {
|
||||
return getWithinContext( executableElement ).getReturnType();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user