Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group nested source mappings #1048

Open
filiphr opened this issue Jan 22, 2017 · 3 comments
Open

Group nested source mappings #1048

filiphr opened this issue Jan 22, 2017 · 3 comments

Comments

@filiphr
Copy link
Member

filiphr commented Jan 22, 2017

Instead of generating a new method for each mapping we might use something similar as in #1046 and use update mapping internally. For example for the mapping:

@Mapper
public interface ArtistToChartEntry {

    @Mappings({
        @Mapping(target = "chartName", ignore = true),
        @Mapping(target = "songTitle", source = "title"),
        @Mapping(target = "artistName", source = "artist.name"),
        @Mapping(target = "recordedAt", source = "artist.label.studio.name"),
        @Mapping(target = "city", source = "artist.label.studio.city"),
        @Mapping(target = "position", ignore = true)
    })
    ChartEntry map(Song song);
}

We generate:

public class ChartEntryToArtistImpl extends ChartEntryToArtist {

    @Override
    public ChartEntry map(Song song) {
        if ( song == null ) {
            return null;
        }

        ChartEntry chartEntry = new ChartEntry();

        chartEntry.setSongTitle( song.getTitle() );
        String city = songArtistLabelStudioCity1( song );
        if ( city != null ) {
            chartEntry.setCity( city );
        }
        String name = songArtistLabelStudioName1( song );
        if ( name != null ) {
            chartEntry.setRecordedAt( name );
        }
        String name1 = songArtistName1( song );
        if ( name1 != null ) {
            chartEntry.setArtistName( name1 );
        }

        return chartEntry;
    }

    private String songArtistLabelStudioCity1(Song song) {

        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 songArtistLabelStudioName1(Song song) {

        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 songArtistName1(Song song) {

        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;
    }
}

The methods songArtistLabelStudioCity1(Song song), songArtistLabelStudioName1(Song song), songArtistName1(Song song) have a lot of duplicated code.

What if we generate this instead:

public class ChartEntryToArtistImpl extends ChartEntryToArtist {

    @Override
    public ChartEntry map(Song song) {
        if ( song == null ) {
            return null;
        }

        ChartEntry chartEntry = new ChartEntry();

        chartEntry.setSongTitle( song.getTitle() );

        updateChartEntryFromArtist( chartEntry, song.getArtist() );

        return chartEntry;
    }

    private void updateChartEntryFromArtist(ChartEntry chartEntry, Artist artist) {
        if ( artist == null ) {
            return;
        }

        if ( artist.getName() != null ) {
            chartEntry.setArtistName( artist.getName() );
        }

        Label label = artist.getLabel();

        if ( label == null ) {
            return;
        }

        Studio studio = label.getStudio();

        if ( studio == null ) {
            return;
        }

        if ( studio.getName() != null ) {
            chartEntry.setRecordedAt( studio.getName() );
        }

        if ( studio.getCity() ) {
            chartEntry.setCity( studio.getCity() );
        }
    }
}

I think that with this the readability is much improved, we gain something small in performance (we don't need to repeat the same conditions multiple times) and we generate less code.

Do you think that this is worth pursuing?

@ankurupadhyay123
Copy link

@filiphr How can we achieve the same?

I am facing this issue

@filiphr
Copy link
Member Author

filiphr commented May 1, 2023

@ankurupadhyay123 as you can see this issue is still open. Which means that you cannot achieve this with MapStruct. We need to implement this

@ankurupadhyay123
Copy link

@filiphr, First of all l thank you so much for building Mapstruct.
It really helped to minimize manual effort.
Waiting this enhancement to be implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants