#1060 Use update methods if there are multiple source parameters

This commit is contained in:
Filip Hrisafov 2017-02-10 19:57:41 +01:00 committed by GitHub
parent 56ea9dd168
commit 40fc5612cb
8 changed files with 579 additions and 7 deletions

View File

@ -303,6 +303,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
for ( Entry<PropertyEntry, MappingOptions> entryByTP : optionsByNestedTarget.entrySet() ) {
Map<Parameter, MappingOptions> optionsBySourceParam = entryByTP.getValue().groupBySourceParameter();
boolean forceUpdateMethod = optionsBySourceParam.keySet().size() > 1;
for ( Entry<Parameter, MappingOptions> entryByParam : optionsBySourceParam.entrySet() ) {
SourceReference sourceRef = new SourceReference.BuilderFromProperty()
@ -319,6 +320,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
.existingVariableNames( existingVariableNames )
.dependsOn( entryByParam.getValue().collectNestedDependsOn() )
.forgeMethodWithMappingOptions( entryByParam.getValue() )
.forceUpdateMethod( forceUpdateMethod )
.build();
unprocessedSourceParameters.remove( sourceRef.getParameter() );

View File

@ -220,7 +220,6 @@ public abstract class MappingMethod extends ModelElement {
@Override
public int hashCode() {
int hash = 7;
hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 83 * hash + (this.parameters != null ? this.parameters.hashCode() : 0);
hash = 83 * hash + (this.returnType != null ? this.returnType.hashCode() : 0);
return hash;
@ -237,10 +236,10 @@ public abstract class MappingMethod extends ModelElement {
if ( getClass() != obj.getClass() ) {
return false;
}
//Do not add name to the equals check.
//Reason: Whenever we forge methods we can reuse mappings if they are the same. However, if we take the name
// into consideration, they'll never be the same, because we create safe methods names.
final MappingMethod other = (MappingMethod) obj;
if ( (this.name == null) ? (other.name != null) : !this.name.equals( other.name ) ) {
return false;
}
if ( this.parameters != other.parameters &&
(this.parameters == null || !this.parameters.equals( other.parameters )) ) {
return false;

View File

@ -71,7 +71,7 @@ public abstract class NormalTypeMappingMethod extends MappingMethod {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
int result = super.hashCode();
result = prime * result + ( ( getResultType() == null ) ? 0 : getResultType().hashCode() );
return result;
}
@ -89,6 +89,10 @@ public abstract class NormalTypeMappingMethod extends MappingMethod {
}
NormalTypeMappingMethod other = (NormalTypeMappingMethod) obj;
if ( !super.equals( obj ) ) {
return false;
}
if ( !getResultType().equals( other.getResultType() ) ) {
return false;
}

View File

@ -187,6 +187,7 @@ public class PropertyMapping extends ModelElement {
private FormattingParameters formattingParameters;
private SelectionParameters selectionParameters;
private MappingOptions forgeMethodWithMappingOptions;
private boolean forceUpdateMethod;
PropertyMappingBuilder() {
super( PropertyMappingBuilder.class );
@ -217,6 +218,16 @@ public class PropertyMapping extends ModelElement {
return this;
}
/**
* Force the created mapping to use update methods when forging a method.
*
* @param forceUpdateMethod whether the mapping should force update method for forged mappings
*/
public PropertyMappingBuilder forceUpdateMethod(boolean forceUpdateMethod) {
this.forceUpdateMethod = forceUpdateMethod;
return this;
}
public PropertyMapping build() {
// handle source
this.rightHandSide = getSourceRHS( sourceReference );
@ -607,8 +618,9 @@ public class PropertyMapping extends ModelElement {
List<Parameter> parameters = new ArrayList<Parameter>( method.getContextParameters() );
Type returnType;
// there's only one case for forging a method with mapping options: nested target properties.
// they should always forge an update method
if ( method.isUpdateMethod() || forgeMethodWithMappingOptions != null ) {
// They should forge an update method only if we set the forceUpdateMethod. This is set to true,
// because we are forging a Mapping for a method with multiple source parameters.
if ( method.isUpdateMethod() || forceUpdateMethod ) {
parameters.add( Parameter.forForgedMappingTarget( targetType ) );
returnType = ctx.getTypeFactory().createVoidType();
}

View File

@ -19,6 +19,7 @@
package org.mapstruct.ap.test.nestedtargetproperties;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry;
@ -36,6 +37,7 @@ import org.mapstruct.ap.test.nestedtargetproperties.source.WaterPlant;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
import org.mapstruct.ap.testutil.runner.GeneratedSource;
/**
*
@ -62,6 +64,13 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
@RunWith(AnnotationProcessorTestRunner.class)
public class NestedTargetPropertiesTest {
@Rule
public GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor(
ChartEntryToArtist.class,
ChartEntryToArtistUpdate.class,
FishTankMapper.class
);
@Test
public void shouldMapNestedTarget() {

View File

@ -0,0 +1,338 @@
/**
* 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.nestedtargetproperties;
import java.util.List;
import javax.annotation.Generated;
import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry;
import org.mapstruct.ap.test.nestedsourceproperties.source.Artist;
import org.mapstruct.ap.test.nestedsourceproperties.source.Chart;
import org.mapstruct.ap.test.nestedsourceproperties.source.Label;
import org.mapstruct.ap.test.nestedsourceproperties.source.Song;
import org.mapstruct.ap.test.nestedsourceproperties.source.Studio;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2017-02-07T21:05:06+0100",
comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)"
)
public class ChartEntryToArtistImpl extends ChartEntryToArtist {
@Override
public Chart map(ChartEntry chartEntry) {
if ( chartEntry == null ) {
return null;
}
Chart chart = new Chart();
chart.setSong( chartEntryToSong( chartEntry ) );
chart.setName( chartEntry.getChartName() );
return chart;
}
@Override
public Chart map(ChartEntry chartEntry1, ChartEntry chartEntry2) {
if ( chartEntry1 == null && chartEntry2 == null ) {
return null;
}
Chart chart = new Chart();
if ( chartEntry1 != null ) {
if ( chart.getSong() == null ) {
chart.setSong( new Song() );
}
chartEntryToSong1( chartEntry1, chart.getSong() );
}
if ( chartEntry2 != null ) {
if ( chart.getSong() == null ) {
chart.setSong( new Song() );
}
chartEntryToSong2( chartEntry2, chart.getSong() );
chart.setName( chartEntry2.getChartName() );
}
return chart;
}
@Override
public ChartEntry map(Chart chart) {
if ( chart == null ) {
return null;
}
ChartEntry chartEntry = new ChartEntry();
String title = chartSongTitle( chart );
if ( title != null ) {
chartEntry.setSongTitle( title );
}
chartEntry.setChartName( chart.getName() );
String city = chartSongArtistLabelStudioCity( chart );
if ( city != null ) {
chartEntry.setCity( city );
}
String name = chartSongArtistLabelStudioName( chart );
if ( name != null ) {
chartEntry.setRecordedAt( name );
}
String name1 = chartSongArtistName( chart );
if ( name1 != null ) {
chartEntry.setArtistName( name1 );
}
List<Integer> positions = chartSongPositions( chart );
if ( positions != null ) {
chartEntry.setPosition( mapPosition( positions ) );
}
return chartEntry;
}
protected Studio chartEntryToStudio(ChartEntry chartEntry) {
if ( chartEntry == null ) {
return null;
}
Studio studio = new Studio();
studio.setCity( chartEntry.getCity() );
studio.setName( chartEntry.getRecordedAt() );
return studio;
}
protected Label chartEntryToLabel(ChartEntry chartEntry) {
if ( chartEntry == null ) {
return null;
}
Label label = new Label();
label.setStudio( chartEntryToStudio( chartEntry ) );
return label;
}
protected Artist chartEntryToArtist(ChartEntry chartEntry) {
if ( chartEntry == null ) {
return null;
}
Artist artist = new Artist();
artist.setLabel( chartEntryToLabel( chartEntry ) );
artist.setName( chartEntry.getArtistName() );
return artist;
}
protected Song chartEntryToSong(ChartEntry chartEntry) {
if ( chartEntry == null ) {
return null;
}
Song song = new Song();
song.setArtist( chartEntryToArtist( chartEntry ) );
List<Integer> list = mapPosition( chartEntry.getPosition() );
if ( list != null ) {
song.setPositions( list );
}
song.setTitle( chartEntry.getSongTitle() );
return song;
}
protected void chartEntryToStudio1(ChartEntry chartEntry, Studio mappingTarget) {
if ( chartEntry == null ) {
return;
}
mappingTarget.setCity( chartEntry.getCity() );
mappingTarget.setName( chartEntry.getRecordedAt() );
}
protected void chartEntryToLabel1(ChartEntry chartEntry, Label mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getStudio() == null ) {
mappingTarget.setStudio( new Studio() );
}
chartEntryToStudio1( chartEntry, mappingTarget.getStudio() );
}
protected void chartEntryToArtist1(ChartEntry chartEntry, Artist mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getLabel() == null ) {
mappingTarget.setLabel( new Label() );
}
chartEntryToLabel1( chartEntry, mappingTarget.getLabel() );
mappingTarget.setName( chartEntry.getArtistName() );
}
protected void chartEntryToSong1(ChartEntry chartEntry, Song mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getArtist() == null ) {
mappingTarget.setArtist( new Artist() );
}
chartEntryToArtist1( chartEntry, mappingTarget.getArtist() );
mappingTarget.setTitle( chartEntry.getSongTitle() );
}
protected void chartEntryToSong2(ChartEntry chartEntry, Song mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getPositions() != null ) {
List<Integer> list = mapPosition( chartEntry.getPosition() );
if ( list != null ) {
mappingTarget.getPositions().clear();
mappingTarget.getPositions().addAll( list );
}
else {
mappingTarget.setPositions( null );
}
}
else {
List<Integer> list = mapPosition( chartEntry.getPosition() );
if ( list != null ) {
mappingTarget.setPositions( list );
}
}
}
private String chartSongTitle(Chart chart) {
if ( chart == null ) {
return null;
}
Song song = chart.getSong();
if ( song == null ) {
return null;
}
String title = song.getTitle();
if ( title == null ) {
return null;
}
return title;
}
private String chartSongArtistLabelStudioCity(Chart chart) {
if ( chart == null ) {
return null;
}
Song song = chart.getSong();
if ( song == null ) {
return null;
}
Artist artist = song.getArtist();
if ( artist == null ) {
return null;
}
Label label = artist.getLabel();
if ( label == null ) {
return null;
}
Studio studio = label.getStudio();
if ( studio == null ) {
return null;
}
String city = studio.getCity();
if ( city == null ) {
return null;
}
return city;
}
private String chartSongArtistLabelStudioName(Chart chart) {
if ( chart == null ) {
return null;
}
Song song = chart.getSong();
if ( song == null ) {
return null;
}
Artist artist = song.getArtist();
if ( artist == null ) {
return null;
}
Label label = artist.getLabel();
if ( label == null ) {
return null;
}
Studio studio = label.getStudio();
if ( studio == null ) {
return null;
}
String name = studio.getName();
if ( name == null ) {
return null;
}
return name;
}
private String chartSongArtistName(Chart chart) {
if ( chart == null ) {
return null;
}
Song song = chart.getSong();
if ( song == null ) {
return null;
}
Artist artist = song.getArtist();
if ( artist == null ) {
return null;
}
String name = artist.getName();
if ( name == null ) {
return null;
}
return name;
}
private List<Integer> chartSongPositions(Chart chart) {
if ( chart == null ) {
return null;
}
Song song = chart.getSong();
if ( song == null ) {
return null;
}
List<Integer> positions = song.getPositions();
if ( positions == null ) {
return null;
}
return positions;
}
}

View File

@ -0,0 +1,116 @@
/**
* 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.nestedtargetproperties;
import java.util.List;
import javax.annotation.Generated;
import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry;
import org.mapstruct.ap.test.nestedsourceproperties.source.Artist;
import org.mapstruct.ap.test.nestedsourceproperties.source.Chart;
import org.mapstruct.ap.test.nestedsourceproperties.source.Label;
import org.mapstruct.ap.test.nestedsourceproperties.source.Song;
import org.mapstruct.ap.test.nestedsourceproperties.source.Studio;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2017-02-07T21:05:06+0100",
comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)"
)
public class ChartEntryToArtistUpdateImpl extends ChartEntryToArtistUpdate {
@Override
public void map(ChartEntry chartEntry, Chart chart) {
if ( chartEntry == null ) {
return;
}
if ( chart.getSong() == null ) {
chart.setSong( new Song() );
}
chartEntryToSong( chartEntry, chart.getSong() );
if ( chartEntry.getChartName() != null ) {
chart.setName( chartEntry.getChartName() );
}
}
protected void chartEntryToStudio(ChartEntry chartEntry, Studio mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( chartEntry.getCity() != null ) {
mappingTarget.setCity( chartEntry.getCity() );
}
if ( chartEntry.getRecordedAt() != null ) {
mappingTarget.setName( chartEntry.getRecordedAt() );
}
}
protected void chartEntryToLabel(ChartEntry chartEntry, Label mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getStudio() == null ) {
mappingTarget.setStudio( new Studio() );
}
chartEntryToStudio( chartEntry, mappingTarget.getStudio() );
}
protected void chartEntryToArtist(ChartEntry chartEntry, Artist mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getLabel() == null ) {
mappingTarget.setLabel( new Label() );
}
chartEntryToLabel( chartEntry, mappingTarget.getLabel() );
if ( chartEntry.getArtistName() != null ) {
mappingTarget.setName( chartEntry.getArtistName() );
}
}
protected void chartEntryToSong(ChartEntry chartEntry, Song mappingTarget) {
if ( chartEntry == null ) {
return;
}
if ( mappingTarget.getArtist() == null ) {
mappingTarget.setArtist( new Artist() );
}
chartEntryToArtist( chartEntry, mappingTarget.getArtist() );
if ( mappingTarget.getPositions() != null ) {
List<Integer> list = mapPosition( chartEntry.getPosition() );
if ( list != null ) {
mappingTarget.getPositions().clear();
mappingTarget.getPositions().addAll( list );
}
}
else {
List<Integer> list = mapPosition( chartEntry.getPosition() );
if ( list != null ) {
mappingTarget.setPositions( list );
}
}
if ( chartEntry.getSongTitle() != null ) {
mappingTarget.setTitle( chartEntry.getSongTitle() );
}
}
}

View File

@ -0,0 +1,92 @@
/**
* 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.nestedtargetproperties;
import javax.annotation.Generated;
import org.mapstruct.ap.test.nestedtargetproperties._target.FishDto;
import org.mapstruct.ap.test.nestedtargetproperties._target.FishTankDto;
import org.mapstruct.ap.test.nestedtargetproperties._target.WaterPlantDto;
import org.mapstruct.ap.test.nestedtargetproperties.source.Fish;
import org.mapstruct.ap.test.nestedtargetproperties.source.FishTank;
import org.mapstruct.ap.test.nestedtargetproperties.source.WaterPlant;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2017-02-07T21:05:06+0100",
comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)"
)
public class FishTankMapperImpl implements FishTankMapper {
@Override
public FishTankDto map(FishTank source) {
if ( source == null ) {
return null;
}
FishTankDto fishTankDto = new FishTankDto();
fishTankDto.setFish( fishTankToFishDto( source ) );
fishTankDto.setPlant( waterPlantToWaterPlantDto( source.getPlant() ) );
return fishTankDto;
}
private String fishTankFishType(FishTank fishTank) {
if ( fishTank == null ) {
return null;
}
Fish fish = fishTank.getFish();
if ( fish == null ) {
return null;
}
String type = fish.getType();
if ( type == null ) {
return null;
}
return type;
}
protected FishDto fishTankToFishDto(FishTank fishTank) {
if ( fishTank == null ) {
return null;
}
FishDto fishDto = new FishDto();
String type = fishTankFishType( fishTank );
if ( type != null ) {
fishDto.setKind( type );
}
return fishDto;
}
protected WaterPlantDto waterPlantToWaterPlantDto(WaterPlant waterPlant) {
if ( waterPlant == null ) {
return null;
}
WaterPlantDto waterPlantDto = new WaterPlantDto();
waterPlantDto.setKind( waterPlant.getKind() );
return waterPlantDto;
}
}