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

Suggestion : custom map function #48

Closed
mmaryo opened this issue Apr 24, 2018 · 5 comments
Closed

Suggestion : custom map function #48

mmaryo opened this issue Apr 24, 2018 · 5 comments

Comments

@mmaryo
Copy link

mmaryo commented Apr 24, 2018

Hello

Sometime mapping cannot be do, so why not enable a custom mapping like this

Mapper<AccountEntity, SfAccount> mapperToSf =
        Mapping.from(AccountEntity.class)
                .to(SfAccount.class)
                .map((source, destination) -> {
                  if (source.getBillingAddress() != null) {
                      destination.setBillingStreet(source.getBillingAddress().getStreet());
                      destination.setBillingCity(source.getBillingAddress().getCity());
                      destination.setBillingPostalCode(source.getBillingAddress().getZip());
                      destination.setBillingState(source.getBillingAddress().getState());
                      destination.setBillingCountry(source.getBillingAddress().getCountry());
                      if (source.getBillingAddress().getLocation() != null) {
                          destination.setBillingLatitude(source.getBillingAddress().getLocation()[0]);
                          destination.setBillingLongitude(source.getBillingAddress().getLocation()[1]);
                      }
                  }
                })
                .omitInSource(AccountEntity::getBillingAddress)
                .omitInDestination(SfAccount::getBillingStreet)
                .omitInDestination(SfAccount::getBillingCity)
                .omitInDestination(SfAccount::getBillingPostalCode)
                .omitInDestination(SfAccount::getBillingState)
                .omitInDestination(SfAccount::getBillingCountry)
                .omitInDestination(SfAccount::getBillingLatitude)
                .omitInDestination(SfAccount::getBillingLongitude)
                .mapper();
@mmaryo mmaryo changed the title Suggestion : map function to do manual mapping Suggestion : custom map function Apr 24, 2018
@schuettec
Copy link
Contributor

schuettec commented Apr 25, 2018

This kind of mapping feature would break testability, which was one of the main design goals of ReMap. In the above case you deactivated ReMap and your mapping reduces to a custom mapping method.

But if I got that right you can resolve the above example in the following way: ReMap supports multiple field mappings. That means you can define multiple transformations for the same source field - this is what you want in your example.

Please have a look:

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import com.remondis.remap.AssertMapping;
import com.remondis.remap.Mapper;
import com.remondis.remap.Mapping;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

public class MapperTest {

  @NoArgsConstructor
  @AllArgsConstructor
  @Data
  @Builder
  public static class AccountEntity {
    private BillingAddress billingAddress;
  }

  @NoArgsConstructor
  @AllArgsConstructor
  @Data
  @Builder
  public static class BillingAddress {
    private String street;
    private String city;
    private String zip;
    private String state;
    private String country;
  }

  @NoArgsConstructor
  @AllArgsConstructor
  @Data
  @Builder
  public static class SfAccount {
    private String billingStreet;
    private String billingCity;
    private String billingPostalCode;
    private String billingState;
    private String billingCountry;

  }

  @Test
  public void multiMapping() {
    Mapper<AccountEntity, SfAccount> mapper = Mapping.from(AccountEntity.class)
        .to(SfAccount.class)
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingStreet)
        .withSkipWhenNull(BillingAddress::getStreet)
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingCity)
        .withSkipWhenNull(BillingAddress::getCity)
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingPostalCode)
        .withSkipWhenNull(BillingAddress::getZip)
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingState)
        .withSkipWhenNull(BillingAddress::getState)
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingCountry)
        .withSkipWhenNull(BillingAddress::getCountry)
        .mapper();
    BillingAddress billingAddress = BillingAddress.builder()
        .city("city")
        .country("country")
        .state("state")
        .street("street")
        .zip("zip")
        .build();
    AccountEntity account = AccountEntity.builder()
        .billingAddress(billingAddress)
        .build();
    SfAccount sfaccount = mapper.map(account);
    assertEquals(billingAddress.getStreet(), sfaccount.getBillingStreet());
    assertEquals(billingAddress.getCity(), sfaccount.getBillingCity());
    assertEquals(billingAddress.getZip(), sfaccount.getBillingPostalCode());
    assertEquals(billingAddress.getState(), sfaccount.getBillingState());
    assertEquals(billingAddress.getCountry(), sfaccount.getBillingCountry());

    // The following would be the assert for your tests:
    AssertMapping.of(mapper)
        .expectReplace(AccountEntity::getBillingAddress, SfAccount::getBillingStreet)
        .andSkipWhenNull()
        .expectReplace(AccountEntity::getBillingAddress, SfAccount::getBillingCity)
        .andSkipWhenNull()
        .expectReplace(AccountEntity::getBillingAddress, SfAccount::getBillingPostalCode)
        .andSkipWhenNull()
        .expectReplace(AccountEntity::getBillingAddress, SfAccount::getBillingState)
        .andSkipWhenNull()
        .expectReplace(AccountEntity::getBillingAddress, SfAccount::getBillingCountry)
        .andSkipWhenNull()
        .ensure();
  }

}

This way you get full support for testability.

@mmaryo
Copy link
Author

mmaryo commented Apr 25, 2018

it's nice thanks !
and have you a solution for
private Double[] location;
in BillingAddress
to be map to
private Double BillingLatitude;
private Double BillingLongitude;
in SfAccount ?

@schuettec
Copy link
Contributor

Just the same way - just add:

        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingLatitude)
        .withSkipWhenNull(billingAddress -> billingAddress.getLocation()[0])
        .replace(AccountEntity::getBillingAddress, SfAccount::getBillingLongitude)
        .withSkipWhenNull(billingAddress -> billingAddress.getLocation()[1])

@mmaryo
Copy link
Author

mmaryo commented Apr 25, 2018

thanks a lot !

@schuettec
Copy link
Contributor

You're welcome!

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

No branches or pull requests

2 participants