mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#3821: Add support for custom exception for subclass exhaustive strategy for @SubclassMapping
--------- Signed-off-by: TangYang <tangyang9464@163.com>
This commit is contained in:
parent
fce73aee6a
commit
6e6fd01a2e
@ -132,6 +132,18 @@ public @interface BeanMapping {
|
|||||||
*/
|
*/
|
||||||
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the exception type to be thrown when a missing subclass implementation is detected
|
||||||
|
* in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}.
|
||||||
|
* <p>
|
||||||
|
* This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to
|
||||||
|
* {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}.
|
||||||
|
*
|
||||||
|
* @return the exception class to throw when missing implementations are found.
|
||||||
|
* Defaults to {@link IllegalArgumentException}.
|
||||||
|
*/
|
||||||
|
Class<? extends Exception> subclassExhaustiveException() default IllegalArgumentException.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default ignore all mappings. All mappings have to be defined manually. No automatic mapping will take place. No
|
* Default ignore all mappings. All mappings have to be defined manually. No automatic mapping will take place. No
|
||||||
* warning will be issued on missing source or target properties.
|
* warning will be issued on missing source or target properties.
|
||||||
|
@ -281,6 +281,18 @@ public @interface Mapper {
|
|||||||
*/
|
*/
|
||||||
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the exception type to be thrown when a missing subclass implementation is detected
|
||||||
|
* in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}.
|
||||||
|
* <p>
|
||||||
|
* This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to
|
||||||
|
* {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}.
|
||||||
|
*
|
||||||
|
* @return the exception class to throw when missing implementations are found.
|
||||||
|
* Defaults to {@link IllegalArgumentException}.
|
||||||
|
*/
|
||||||
|
Class<? extends Exception> subclassExhaustiveException() default IllegalArgumentException.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether to use field or constructor injection. This is only used on annotated based component models
|
* Determines whether to use field or constructor injection. This is only used on annotated based component models
|
||||||
* such as CDI, Spring and JSR 330.
|
* such as CDI, Spring and JSR 330.
|
||||||
|
@ -249,6 +249,18 @@ public @interface MapperConfig {
|
|||||||
*/
|
*/
|
||||||
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the exception type to be thrown when a missing subclass implementation is detected
|
||||||
|
* in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}.
|
||||||
|
* <p>
|
||||||
|
* This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to
|
||||||
|
* {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}.
|
||||||
|
*
|
||||||
|
* @return the exception class to throw when missing implementations are found.
|
||||||
|
* Defaults to {@link IllegalArgumentException}.
|
||||||
|
*/
|
||||||
|
Class<? extends Exception> subclassExhaustiveException() default IllegalArgumentException.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether to use field or constructor injection. This is only used on annotated based component models
|
* Determines whether to use field or constructor injection. This is only used on annotated based component models
|
||||||
* such as CDI, Spring and JSR 330.
|
* such as CDI, Spring and JSR 330.
|
||||||
|
@ -100,6 +100,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
private final String finalizedResultName;
|
private final String finalizedResultName;
|
||||||
private final List<LifecycleCallbackMethodReference> beforeMappingReferencesWithFinalizedReturnType;
|
private final List<LifecycleCallbackMethodReference> beforeMappingReferencesWithFinalizedReturnType;
|
||||||
private final List<LifecycleCallbackMethodReference> afterMappingReferencesWithFinalizedReturnType;
|
private final List<LifecycleCallbackMethodReference> afterMappingReferencesWithFinalizedReturnType;
|
||||||
|
private final Type subclassExhaustiveException;
|
||||||
|
|
||||||
private final MappingReferences mappingReferences;
|
private final MappingReferences mappingReferences;
|
||||||
|
|
||||||
@ -378,6 +379,11 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeMirror subclassExhaustiveException = method.getOptions()
|
||||||
|
.getBeanMapping()
|
||||||
|
.getSubclassExhaustiveException();
|
||||||
|
Type subclassExhaustiveExceptionType = ctx.getTypeFactory().getType( subclassExhaustiveException );
|
||||||
|
|
||||||
List<SubclassMapping> subclasses = new ArrayList<>();
|
List<SubclassMapping> subclasses = new ArrayList<>();
|
||||||
for ( SubclassMappingOptions subclassMappingOptions : method.getOptions().getSubclassMappings() ) {
|
for ( SubclassMappingOptions subclassMappingOptions : method.getOptions().getSubclassMappings() ) {
|
||||||
subclasses.add( createSubclassMapping( subclassMappingOptions ) );
|
subclasses.add( createSubclassMapping( subclassMappingOptions ) );
|
||||||
@ -451,7 +457,8 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
finalizeMethod,
|
finalizeMethod,
|
||||||
mappingReferences,
|
mappingReferences,
|
||||||
subclasses,
|
subclasses,
|
||||||
presenceChecksByParameter
|
presenceChecksByParameter,
|
||||||
|
subclassExhaustiveExceptionType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1954,7 +1961,8 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
MethodReference finalizerMethod,
|
MethodReference finalizerMethod,
|
||||||
MappingReferences mappingReferences,
|
MappingReferences mappingReferences,
|
||||||
List<SubclassMapping> subclassMappings,
|
List<SubclassMapping> subclassMappings,
|
||||||
Map<String, PresenceCheck> presenceChecksByParameter) {
|
Map<String, PresenceCheck> presenceChecksByParameter,
|
||||||
|
Type subclassExhaustiveException) {
|
||||||
super(
|
super(
|
||||||
method,
|
method,
|
||||||
annotations,
|
annotations,
|
||||||
@ -1969,6 +1977,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
this.propertyMappings = propertyMappings;
|
this.propertyMappings = propertyMappings;
|
||||||
this.returnTypeBuilder = returnTypeBuilder;
|
this.returnTypeBuilder = returnTypeBuilder;
|
||||||
this.finalizerMethod = finalizerMethod;
|
this.finalizerMethod = finalizerMethod;
|
||||||
|
this.subclassExhaustiveException = subclassExhaustiveException;
|
||||||
if ( this.finalizerMethod != null ) {
|
if ( this.finalizerMethod != null ) {
|
||||||
this.finalizedResultName =
|
this.finalizedResultName =
|
||||||
Strings.getSafeVariableName( getResultName() + "Result", existingVariableNames );
|
Strings.getSafeVariableName( getResultName() + "Result", existingVariableNames );
|
||||||
@ -2017,6 +2026,10 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
this.subclassMappings = subclassMappings;
|
this.subclassMappings = subclassMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getSubclassExhaustiveException() {
|
||||||
|
return subclassExhaustiveException;
|
||||||
|
}
|
||||||
|
|
||||||
public List<PropertyMapping> getConstantMappings() {
|
public List<PropertyMapping> getConstantMappings() {
|
||||||
return constantMappings;
|
return constantMappings;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.gem.BeanMappingGem;
|
import org.mapstruct.ap.internal.gem.BeanMappingGem;
|
||||||
import org.mapstruct.ap.internal.gem.BuilderGem;
|
import org.mapstruct.ap.internal.gem.BuilderGem;
|
||||||
@ -182,6 +183,14 @@ public class BeanMappingOptions extends DelegatingOptions {
|
|||||||
.orElse( next().getSubclassExhaustiveStrategy() );
|
.orElse( next().getSubclassExhaustiveStrategy() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeMirror getSubclassExhaustiveException() {
|
||||||
|
return Optional.ofNullable( beanMapping ).map( BeanMappingGem::subclassExhaustiveException )
|
||||||
|
.filter( GemValue::hasValue )
|
||||||
|
.map( GemValue::getValue )
|
||||||
|
.orElse( next().getSubclassExhaustiveException() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReportingPolicyGem unmappedTargetPolicy() {
|
public ReportingPolicyGem unmappedTargetPolicy() {
|
||||||
return Optional.ofNullable( beanMapping ).map( BeanMappingGem::unmappedTargetPolicy )
|
return Optional.ofNullable( beanMapping ).map( BeanMappingGem::unmappedTargetPolicy )
|
||||||
|
@ -131,6 +131,10 @@ public class DefaultOptions extends DelegatingOptions {
|
|||||||
return SubclassExhaustiveStrategyGem.valueOf( mapper.subclassExhaustiveStrategy().getDefaultValue() );
|
return SubclassExhaustiveStrategyGem.valueOf( mapper.subclassExhaustiveStrategy().getDefaultValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeMirror getSubclassExhaustiveException() {
|
||||||
|
return mapper.subclassExhaustiveException().getDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
||||||
NullValueMappingStrategyGem nullValueIterableMappingStrategy = options.getNullValueIterableMappingStrategy();
|
NullValueMappingStrategyGem nullValueIterableMappingStrategy = options.getNullValueIterableMappingStrategy();
|
||||||
if ( nullValueIterableMappingStrategy != null ) {
|
if ( nullValueIterableMappingStrategy != null ) {
|
||||||
|
@ -106,6 +106,10 @@ public abstract class DelegatingOptions {
|
|||||||
return next.getSubclassExhaustiveStrategy();
|
return next.getSubclassExhaustiveStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeMirror getSubclassExhaustiveException() {
|
||||||
|
return next.getSubclassExhaustiveException();
|
||||||
|
}
|
||||||
|
|
||||||
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
||||||
return next.getNullValueIterableMappingStrategy();
|
return next.getNullValueIterableMappingStrategy();
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,12 @@ public class MapperConfigOptions extends DelegatingOptions {
|
|||||||
next().getSubclassExhaustiveStrategy();
|
next().getSubclassExhaustiveStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeMirror getSubclassExhaustiveException() {
|
||||||
|
return mapperConfig.subclassExhaustiveException().hasValue() ?
|
||||||
|
mapperConfig.subclassExhaustiveException().get() :
|
||||||
|
next().getSubclassExhaustiveException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
||||||
if ( mapperConfig.nullValueIterableMappingStrategy().hasValue() ) {
|
if ( mapperConfig.nullValueIterableMappingStrategy().hasValue() ) {
|
||||||
|
@ -170,6 +170,13 @@ public class MapperOptions extends DelegatingOptions {
|
|||||||
next().getSubclassExhaustiveStrategy();
|
next().getSubclassExhaustiveStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeMirror getSubclassExhaustiveException() {
|
||||||
|
return mapper.subclassExhaustiveException().hasValue() ?
|
||||||
|
mapper.subclassExhaustiveException().get() :
|
||||||
|
next().getSubclassExhaustiveException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() {
|
||||||
if ( mapper.nullValueIterableMappingStrategy().hasValue() ) {
|
if ( mapper.nullValueIterableMappingStrategy().hasValue() ) {
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
else {
|
else {
|
||||||
</#if>
|
</#if>
|
||||||
<#if isAbstractReturnType()>
|
<#if isAbstractReturnType()>
|
||||||
throw new IllegalArgumentException("Not all subclasses are supported for this mapping. Missing for " + ${subclassMappings[0].sourceArgument}.getClass());
|
throw new <@includeModel object=subclassExhaustiveException />("Not all subclasses are supported for this mapping. Missing for " + ${subclassMappings[0].sourceArgument}.getClass());
|
||||||
<#else>
|
<#else>
|
||||||
<#if !existingInstanceMapping>
|
<#if !existingInstanceMapping>
|
||||||
<#if hasConstructorMappings()>
|
<#if hasConstructorMappings()>
|
||||||
|
@ -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.ap.test.subclassmapping.abstractsuperclass;
|
||||||
|
|
||||||
|
import org.mapstruct.BeanMapping;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.SubclassExhaustiveStrategy;
|
||||||
|
import org.mapstruct.SubclassMapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CustomExceptionSubclassMapper {
|
||||||
|
CustomExceptionSubclassMapper INSTANCE = Mappers.getMapper( CustomExceptionSubclassMapper.class );
|
||||||
|
|
||||||
|
@BeanMapping(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION,
|
||||||
|
subclassExhaustiveException = CustomSubclassMappingException.class)
|
||||||
|
@SubclassMapping(source = Car.class, target = CarDto.class)
|
||||||
|
@SubclassMapping(source = Bike.class, target = BikeDto.class)
|
||||||
|
VehicleDto map(AbstractVehicle vehicle);
|
||||||
|
|
||||||
|
VehicleCollectionDto mapInverse(VehicleCollection vehicles);
|
||||||
|
}
|
@ -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.subclassmapping.abstractsuperclass;
|
||||||
|
|
||||||
|
public class CustomSubclassMappingException extends RuntimeException {
|
||||||
|
public CustomSubclassMappingException(String message) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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.subclassmapping.abstractsuperclass;
|
||||||
|
|
||||||
|
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.assertThatThrownBy;
|
||||||
|
|
||||||
|
@IssueKey("3821")
|
||||||
|
@WithClasses({
|
||||||
|
Bike.class,
|
||||||
|
BikeDto.class,
|
||||||
|
Car.class,
|
||||||
|
CarDto.class,
|
||||||
|
Motorcycle.class,
|
||||||
|
VehicleCollection.class,
|
||||||
|
VehicleCollectionDto.class,
|
||||||
|
AbstractVehicle.class,
|
||||||
|
VehicleDto.class,
|
||||||
|
CustomSubclassMappingException.class,
|
||||||
|
CustomExceptionSubclassMapper.class
|
||||||
|
})
|
||||||
|
public class CustomSubclassMappingExceptionTest {
|
||||||
|
|
||||||
|
private static final String EXPECTED_ERROR_MESSAGE = "Not all subclasses are supported for this mapping. "
|
||||||
|
+ "Missing for class org.mapstruct.ap.test.subclassmapping.abstractsuperclass.Motorcycle";
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
void customExceptionIsThrownForUnknownSubclass() {
|
||||||
|
VehicleCollection vehicles = new VehicleCollection();
|
||||||
|
vehicles.getVehicles().add( new Car() );
|
||||||
|
vehicles.getVehicles().add( new Motorcycle() ); // undefine subclass
|
||||||
|
|
||||||
|
assertThatThrownBy( () -> CustomExceptionSubclassMapper.INSTANCE.mapInverse( vehicles ) )
|
||||||
|
.isInstanceOf( CustomSubclassMappingException.class )
|
||||||
|
.hasMessage( EXPECTED_ERROR_MESSAGE );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
void customExceptionIsThrownForSingleVehicle() {
|
||||||
|
AbstractVehicle vehicle = new Motorcycle(); // undefine subclass
|
||||||
|
|
||||||
|
assertThatThrownBy( () -> CustomExceptionSubclassMapper.INSTANCE.map( vehicle ) )
|
||||||
|
.isInstanceOf( CustomSubclassMappingException.class )
|
||||||
|
.hasMessage( EXPECTED_ERROR_MESSAGE );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses({ MapperConfigSubclassMapper.class })
|
||||||
|
void customExceptionIsThrownForMapperConfig() {
|
||||||
|
VehicleCollection vehicles = new VehicleCollection();
|
||||||
|
vehicles.getVehicles().add( new Car() );
|
||||||
|
vehicles.getVehicles().add( new Motorcycle() ); // undefined subclass
|
||||||
|
|
||||||
|
assertThatThrownBy( () -> MapperConfigSubclassMapper.INSTANCE.mapInverse( vehicles ) )
|
||||||
|
.isInstanceOf( CustomSubclassMappingException.class )
|
||||||
|
.hasMessage( EXPECTED_ERROR_MESSAGE );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses({ MapperSubclassMapper.class })
|
||||||
|
void customExceptionIsThrownForMapper() {
|
||||||
|
VehicleCollection vehicles = new VehicleCollection();
|
||||||
|
vehicles.getVehicles().add( new Car() );
|
||||||
|
vehicles.getVehicles().add( new Motorcycle() ); // undefined subclass
|
||||||
|
|
||||||
|
assertThatThrownBy( () -> MapperSubclassMapper.INSTANCE.mapInverse( vehicles ) )
|
||||||
|
.isInstanceOf( CustomSubclassMappingException.class )
|
||||||
|
.hasMessage( EXPECTED_ERROR_MESSAGE );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.subclassmapping.abstractsuperclass;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MapperConfig;
|
||||||
|
import org.mapstruct.SubclassExhaustiveStrategy;
|
||||||
|
import org.mapstruct.SubclassMapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper(config = MapperConfigSubclassMapper.Config.class)
|
||||||
|
public interface MapperConfigSubclassMapper {
|
||||||
|
|
||||||
|
MapperConfigSubclassMapper INSTANCE = Mappers.getMapper( MapperConfigSubclassMapper.class );
|
||||||
|
|
||||||
|
@MapperConfig(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION,
|
||||||
|
subclassExhaustiveException = CustomSubclassMappingException.class)
|
||||||
|
interface Config {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubclassMapping(source = Car.class, target = CarDto.class)
|
||||||
|
@SubclassMapping(source = Bike.class, target = BikeDto.class)
|
||||||
|
VehicleDto map(AbstractVehicle vehicle);
|
||||||
|
|
||||||
|
VehicleCollectionDto mapInverse(VehicleCollection vehicles);
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.subclassmapping.abstractsuperclass;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.SubclassExhaustiveStrategy;
|
||||||
|
import org.mapstruct.SubclassMapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION,
|
||||||
|
subclassExhaustiveException = CustomSubclassMappingException.class)
|
||||||
|
public interface MapperSubclassMapper {
|
||||||
|
|
||||||
|
MapperSubclassMapper INSTANCE = Mappers.getMapper( MapperSubclassMapper.class );
|
||||||
|
|
||||||
|
@SubclassMapping(source = Car.class, target = CarDto.class)
|
||||||
|
@SubclassMapping(source = Bike.class, target = BikeDto.class)
|
||||||
|
VehicleDto map(AbstractVehicle vehicle);
|
||||||
|
|
||||||
|
VehicleCollectionDto mapInverse(VehicleCollection vehicles);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user