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

Mapping from Map to Map and specify source and target keys #3303

Open
JM92103 opened this issue Jun 7, 2023 · 1 comment
Open

Mapping from Map to Map and specify source and target keys #3303

JM92103 opened this issue Jun 7, 2023 · 1 comment
Labels
feature up-for-grabs Issues targeted for community contribution

Comments

@JM92103
Copy link

JM92103 commented Jun 7, 2023

Use case

I have a use case where I need to convert a Map<String, String> to a Map<String, String> but manipulate the keys. Currently I am trying to do

@Mapping(target = "value",  source = "Cash_Amount")
@Mapping(target = "valueDate",  source = "Date_Of_Money_Movement")
Map<String, String> fromCsvToStpTransaction(Map<String, String> rec);

But the generated code is ignoring these values and just doing a basic Map conversion like below

@Override
public Map<String, String> fromCsvToStpTransaction(Map<String, String> rec) {
    if ( rec == null ) {
        return null;
    }

    Map<String, String> map = new LinkedHashMap<String, String>( Math.max( (int) ( rec.size() / .75f ) + 1, 16 ) );

    for ( java.util.Map.Entry<String, String> entry : rec.entrySet() ) {
        String key = entry.getKey();
        String value = entry.getValue();
        map.put( key, value );
    }

    return map;
}

Generated Code

I would expect the generated code to look something like

@Override
public Map<String, String> fromCsvToStpTransaction(Map<String, String> rec) {
    if ( rec == null ) {
        return null;
    }

    Map<String, String> map = new LinkedHashMap<String, String>( Math.max( (int) ( rec.size() / .75f ) + 1, 16 ) );

    if ( rec.containsKey("Cash_Amount") {
        map.put("value", rec.get("Cash_Amount");
    }

    if ( rec.containsKey("Date_Of_Money_Movement") {
        map.put("valueDate", rec.get("Date_Of_Money_Movement");
    }
    //an else would be nice as well to assume mapping of non matched values 
    else {
        for ( java.util.Map.Entry<String, String> entry : rec.entrySet() ) {
            String key = entry.getKey();
            String value = entry.getValue();
            map.put( key, value );
        }
    }

    return map;
}

Possible workarounds

No response

MapStruct Version

1.5.5

@JM92103 JM92103 changed the title Mapping from Map to Map and specify source and target values Mapping from Map to Map and specify source and target keys Jun 7, 2023
@filiphr
Copy link
Member

filiphr commented Jun 16, 2023

This is a valid request @JM92103, I don't see why something like this shouldn't be supported. However, I would expect the implementation to look like:

public class MyMapperImpl implements MyMapper {

    private final Map<String, String> fromCsvToStpTransactionKeyMappings;

    public MyMapperImpl() {
        this.fromCsvToStpTransactionKeyMappings = new HashMap<>();
        this.fromCsvToStpTransactionKeyMappings.put( "Cash_Amount", "value" );
        this.fromCsvToStpTransactionKeyMappings.put( "Date_Of_Money_Movement", "valueDate" );
    }

    @Override
    public Map<String, String> fromCsvToStpTransaction(Map<String, String> rec) {
        if ( rec == null ) {
            return null;
        }

        Map<String, String> map = new LinkedHashMap<>( Math.max( (int) ( rec.size() / .75f ) + 1, 16 ) );

        for ( java.util.Map.Entry<String, String> entry : rec.entrySet() ) {
            String key = entry.getKey();
            String value = entry.getValue();
            map.put( this.fromCsvToStpTransactionKeyMappings.getOrDefault( key, key ), value );
        }

        return map;
    }
}

The fromCsvToStpTransactionKeyMappings should only be created if the mapping method has @Mapping.

I'll put this for "up for grabs" in case someone from the community is interested in working on this.

@filiphr filiphr added feature up-for-grabs Issues targeted for community contribution labels Jun 16, 2023
thunderhook added a commit to thunderhook/mapstruct that referenced this issue Aug 28, 2023
thunderhook added a commit to thunderhook/mapstruct that referenced this issue Aug 28, 2023
thunderhook added a commit to thunderhook/mapstruct that referenced this issue Aug 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature up-for-grabs Issues targeted for community contribution
Projects
None yet
Development

No branches or pull requests

2 participants