mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#3711: Support generic @Context
Signed-off-by: TangYang <tangyang9464@163.com>
This commit is contained in:
parent
6b6600c370
commit
5464c3cff8
@ -114,7 +114,12 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
}
|
||||
|
||||
List<SourceMethod> prototypeMethods = retrievePrototypeMethods( mapperTypeElement, mapperOptions );
|
||||
return retrieveMethods( mapperTypeElement, mapperTypeElement, mapperOptions, prototypeMethods );
|
||||
return retrieveMethods(
|
||||
typeFactory.getType( mapperTypeElement.asType() ),
|
||||
mapperTypeElement,
|
||||
mapperOptions,
|
||||
prototypeMethods
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -166,19 +171,21 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
/**
|
||||
* Retrieves the mapping methods declared by the given mapper type.
|
||||
*
|
||||
* @param usedMapper The type of interest (either the mapper to implement or a used mapper via @uses annotation)
|
||||
* @param usedMapperType The type of interest (either the mapper to implement, a used mapper via @uses annotation,
|
||||
* or a parameter type annotated with @Context)
|
||||
* @param mapperToImplement the top level type (mapper) that requires implementation
|
||||
* @param mapperOptions the mapper config
|
||||
* @param prototypeMethods prototype methods defined in mapper config type
|
||||
* @return All mapping methods declared by the given type
|
||||
*/
|
||||
private List<SourceMethod> retrieveMethods(TypeElement usedMapper, TypeElement mapperToImplement,
|
||||
private List<SourceMethod> retrieveMethods(Type usedMapperType, TypeElement mapperToImplement,
|
||||
MapperOptions mapperOptions, List<SourceMethod> prototypeMethods) {
|
||||
List<SourceMethod> methods = new ArrayList<>();
|
||||
|
||||
TypeElement usedMapper = usedMapperType.getTypeElement();
|
||||
for ( ExecutableElement executable : elementUtils.getAllEnclosedExecutableElements( usedMapper ) ) {
|
||||
SourceMethod method = getMethod(
|
||||
usedMapper,
|
||||
usedMapperType,
|
||||
executable,
|
||||
mapperToImplement,
|
||||
mapperOptions,
|
||||
@ -195,7 +202,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
TypeElement usesMapperElement = asTypeElement( mapper );
|
||||
if ( !mapperToImplement.equals( usesMapperElement ) ) {
|
||||
methods.addAll( retrieveMethods(
|
||||
usesMapperElement,
|
||||
typeFactory.getType( mapper ),
|
||||
mapperToImplement,
|
||||
mapperOptions,
|
||||
prototypeMethods ) );
|
||||
@ -218,13 +225,13 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
return (TypeElement) type.asElement();
|
||||
}
|
||||
|
||||
private SourceMethod getMethod(TypeElement usedMapper,
|
||||
private SourceMethod getMethod(Type usedMapperType,
|
||||
ExecutableElement method,
|
||||
TypeElement mapperToImplement,
|
||||
MapperOptions mapperOptions,
|
||||
List<SourceMethod> prototypeMethods) {
|
||||
|
||||
ExecutableType methodType = typeFactory.getMethodType( (DeclaredType) usedMapper.asType(), method );
|
||||
TypeElement usedMapper = usedMapperType.getTypeElement();
|
||||
ExecutableType methodType = typeFactory.getMethodType( (DeclaredType) usedMapperType.getTypeMirror(), method );
|
||||
List<Parameter> parameters = typeFactory.getParameters( methodType, method );
|
||||
Type returnType = typeFactory.getReturnType( methodType );
|
||||
|
||||
@ -357,7 +364,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
continue;
|
||||
}
|
||||
List<SourceMethod> contextParamMethods = retrieveMethods(
|
||||
contextParam.getType().getTypeElement(),
|
||||
contextParam.getType(),
|
||||
mapperToImplement,
|
||||
mapperConfig,
|
||||
Collections.emptyList() );
|
||||
|
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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.bugs._3711;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
|
||||
interface BaseMapper<T, E> {
|
||||
E toEntity(T s, @Context JpaContext<E> ctx);
|
||||
}
|
@ -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.ap.test.bugs._3711;
|
||||
|
||||
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;
|
||||
|
||||
@WithClasses({
|
||||
ParentEntity.class,
|
||||
ParentDto.class,
|
||||
JpaContext.class,
|
||||
SourceTargetMapper.class,
|
||||
BaseMapper.class,
|
||||
})
|
||||
@IssueKey("3711")
|
||||
class Issue3711Test {
|
||||
@ProcessorTest
|
||||
void shouldGenerateContextMethod() {
|
||||
JpaContext<ParentEntity> jpaContext = new JpaContext<>();
|
||||
SourceTargetMapper.INSTANCE.toEntity( new ParentDto(), jpaContext );
|
||||
|
||||
assertThat( jpaContext.getInvokedMethods() )
|
||||
.containsExactly( "beforeMapping", "afterMapping" );
|
||||
}
|
||||
}
|
@ -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.ap.test.bugs._3711;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.BeforeMapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
|
||||
public class JpaContext<T> {
|
||||
private final List<String> invokedMethods = new ArrayList<>();
|
||||
|
||||
@BeforeMapping
|
||||
void beforeMapping(@MappingTarget T parentEntity) {
|
||||
invokedMethods.add( "beforeMapping" );
|
||||
}
|
||||
|
||||
@AfterMapping
|
||||
void afterMapping(@MappingTarget T parentEntity) {
|
||||
invokedMethods.add( "afterMapping" );
|
||||
}
|
||||
|
||||
public List<String> getInvokedMethods() {
|
||||
return invokedMethods;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.bugs._3711;
|
||||
|
||||
public class ParentDto {
|
||||
private String value;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.bugs._3711;
|
||||
|
||||
public class ParentEntity {
|
||||
private String value;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.bugs._3711;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface SourceTargetMapper extends BaseMapper<ParentDto, ParentEntity> {
|
||||
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
||||
|
||||
ParentEntity toDTO(ParentDto dto);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user