mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#1065 @InheritReverseConfiguration from MappingConfig
This commit is contained in:
parent
13c3d878d8
commit
fa20d03051
@ -76,6 +76,7 @@ public class SourceMethod implements Method {
|
||||
private List<String> parameterNames;
|
||||
|
||||
private List<SourceMethod> applicablePrototypeMethods;
|
||||
private List<SourceMethod> applicableReversePrototypeMethods;
|
||||
|
||||
private Boolean isBeanMapping;
|
||||
private Boolean isEnumMapping;
|
||||
@ -312,11 +313,11 @@ public class SourceMethod implements Method {
|
||||
}
|
||||
|
||||
public boolean reverses(SourceMethod method) {
|
||||
return getDeclaringMapper() == null
|
||||
&& isAbstract()
|
||||
return method.getDeclaringMapper() == null
|
||||
&& method.isAbstract()
|
||||
&& getSourceParameters().size() == 1 && method.getSourceParameters().size() == 1
|
||||
&& equals( first( getSourceParameters() ).getType(), method.getResultType() )
|
||||
&& equals( getResultType(), first( method.getSourceParameters() ).getType() );
|
||||
&& first( getSourceParameters() ).getType().isAssignableTo( method.getResultType() )
|
||||
&& getResultType().isAssignableTo( first( method.getSourceParameters() ).getType() );
|
||||
}
|
||||
|
||||
public boolean isSame(SourceMethod method) {
|
||||
@ -486,6 +487,20 @@ public class SourceMethod implements Method {
|
||||
return applicablePrototypeMethods;
|
||||
}
|
||||
|
||||
public List<SourceMethod> getApplicableReversePrototypeMethods() {
|
||||
if ( applicableReversePrototypeMethods == null ) {
|
||||
applicableReversePrototypeMethods = new ArrayList<SourceMethod>();
|
||||
|
||||
for ( SourceMethod prototype : prototypeMethods ) {
|
||||
if ( reverses( prototype ) ) {
|
||||
applicableReversePrototypeMethods.add( prototype );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return applicableReversePrototypeMethods;
|
||||
}
|
||||
|
||||
private static boolean allParametersAreAssignable(List<Parameter> fromParams, List<Parameter> toParams) {
|
||||
if ( fromParams.size() == toParams.size() ) {
|
||||
Set<Parameter> unaccountedToParams = new HashSet<Parameter>( toParams );
|
||||
|
@ -424,10 +424,15 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
initializingMethods.add( method );
|
||||
|
||||
MappingOptions mappingOptions = method.getMappingOptions();
|
||||
List<SourceMethod> applicablePrototypeMethods = method.getApplicablePrototypeMethods();
|
||||
List<SourceMethod> applicableReversePrototypeMethods = method.getApplicableReversePrototypeMethods();
|
||||
|
||||
MappingOptions inverseMappingOptions =
|
||||
getInverseMappingOptions( availableMethods, method, initializingMethods, mapperConfig );
|
||||
getInverseMappingOptions( join( availableMethods, applicableReversePrototypeMethods ),
|
||||
method,
|
||||
initializingMethods,
|
||||
mapperConfig );
|
||||
|
||||
List<SourceMethod> applicablePrototypeMethods = method.getApplicablePrototypeMethods();
|
||||
|
||||
MappingOptions templateMappingOptions =
|
||||
getTemplateMappingOptions(
|
||||
@ -457,6 +462,21 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
Message.INHERITCONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH,
|
||||
Strings.join( applicablePrototypeMethods, ", " ) );
|
||||
}
|
||||
|
||||
if ( applicableReversePrototypeMethods.size() == 1 ) {
|
||||
mappingOptions.applyInheritedOptions(
|
||||
first( applicableReversePrototypeMethods ).getMappingOptions(),
|
||||
true,
|
||||
method,
|
||||
messager,
|
||||
typeFactory );
|
||||
}
|
||||
else if ( applicableReversePrototypeMethods.size() > 1 ) {
|
||||
messager.printMessage(
|
||||
method.getExecutable(),
|
||||
Message.INHERITINVERSECONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH,
|
||||
Strings.join( applicablePrototypeMethods, ", " ) );
|
||||
}
|
||||
}
|
||||
|
||||
mappingOptions.markAsFullyInitialized();
|
||||
@ -497,7 +517,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
// method is configured as being reverse method, collect candidates
|
||||
List<SourceMethod> candidates = new ArrayList<SourceMethod>();
|
||||
for ( SourceMethod oneMethod : rawMethods ) {
|
||||
if ( oneMethod.reverses( method ) ) {
|
||||
if ( method.reverses( oneMethod ) ) {
|
||||
candidates.add( oneMethod );
|
||||
}
|
||||
}
|
||||
@ -559,7 +579,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
* Returns the configuring forward method's options in case the given method is annotated with
|
||||
* {@code @InheritConfiguration} and exactly one such configuring method can unambiguously be selected (as per the
|
||||
* source/target type and optionally the name given via {@code @InheritConfiguration}). The method cannot be marked
|
||||
* forward mapping itself (hence 'ohter'). And neither can it contain an {@code @InheritReverseConfiguration}
|
||||
* forward mapping itself (hence 'other'). And neither can it contain an {@code @InheritReverseConfiguration}
|
||||
*/
|
||||
private MappingOptions getTemplateMappingOptions(List<SourceMethod> rawMethods, SourceMethod method,
|
||||
List<SourceMethod> initializingMethods,
|
||||
|
@ -113,6 +113,7 @@ public enum Message {
|
||||
INHERITCONFIGURATION_DUPLICATE_MATCHES( "Given name \"%s\" matches several candidate methods: %s." ),
|
||||
INHERITCONFIGURATION_NO_NAME_MATCH( "Given name \"%s\" does not match the only candidate. Did you mean: \"%s\"." ),
|
||||
INHERITCONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH( "More than one configuration prototype method is applicable. Use @InheritConfiguration to select one of them explicitly: %s." ),
|
||||
INHERITINVERSECONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH( "More than one configuration prototype method is applicable. Use @InheritInverseConfiguration to select one of them explicitly: %s." ),
|
||||
INHERITCONFIGURATION_CYCLE( "Cycle detected while evaluating inherited configurations. Inheritance path: %s" ),
|
||||
|
||||
VALUEMAPPING_DUPLICATE_SOURCE( "Source value mapping: \"%s\" cannot be mapped more than once." ),
|
||||
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.inheritfromconfig;
|
||||
|
||||
import org.mapstruct.InheritInverseConfiguration;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingInheritanceStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@Mapper(
|
||||
config = AutoInheritedConfig.class,
|
||||
mappingInheritanceStrategy = MappingInheritanceStrategy.EXPLICIT
|
||||
)
|
||||
public abstract class CarMapperReverseWithExplicitInheritance {
|
||||
public static final CarMapperReverseWithExplicitInheritance INSTANCE =
|
||||
Mappers.getMapper( CarMapperReverseWithExplicitInheritance.class );
|
||||
|
||||
@InheritInverseConfiguration(name = "baseDtoToEntity")
|
||||
@Mapping( target = "colour", source = "color" )
|
||||
public abstract CarDto toCarDto(CarEntity entity);
|
||||
|
||||
}
|
@ -125,6 +125,21 @@ public class InheritFromConfigTest {
|
||||
assertThat( carDto.getId() ).isEqualTo( 42L );
|
||||
}
|
||||
|
||||
@Test
|
||||
@IssueKey( "1065" )
|
||||
@WithClasses({ CarMapperReverseWithExplicitInheritance.class } )
|
||||
public void explicitInheritedMappingIsAppliedInReverseDirectlyFromConfig() {
|
||||
|
||||
CarEntity carEntity = new CarEntity();
|
||||
carEntity.setColor( "red" );
|
||||
carEntity.setPrimaryKey( 42L );
|
||||
|
||||
CarDto carDto = CarMapperReverseWithExplicitInheritance.INSTANCE.toCarDto( carEntity );
|
||||
|
||||
assertThat( carDto.getColour() ).isEqualTo( "red" );
|
||||
assertThat( carDto.getId() ).isEqualTo( 42L );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void explicitInheritedMappingWithTwoLevelsIsOverriddenAtMethodLevel() {
|
||||
CarDto carDto = newTestDto();
|
||||
|
@ -37,5 +37,5 @@ public interface ArtistToChartEntryConfig {
|
||||
@Mapping(target = "artistName", source = "artist.name"),
|
||||
@Mapping(target = "chartName", ignore = true )
|
||||
})
|
||||
BaseChartEntry mapForward( Song song );
|
||||
BaseChartEntry mapForwardConfig( Song song );
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public abstract class ArtistToChartEntryWithConfigReverse {
|
||||
})
|
||||
abstract ChartEntryWithBase mapForward(Song song);
|
||||
|
||||
@InheritInverseConfiguration
|
||||
@InheritInverseConfiguration( name = "mapForward" )
|
||||
@Mapping(target = "positions", ignore = true)
|
||||
abstract Song mapReverse(ChartEntryWithBase ce);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user