mapping from flat protobuf message to class with inner classes using mapStruct

Viewed 185

I need to use mapStruct to write a mapping from message AddressProto to the class Address. But message AddressProto consists only of string fields while Address class has inner classes.

I have written such a mapper so far, but due to the difference between the message structure and the class, I don’t know how to correctly map fields from message AddressProto to class Address and back.

@Mapper(config = MapstructConfig.class, unmappedTargetPolicy = ReportingPolicy.ERROR)
public abstract class AddressProtoMapper {

  // from proto to object
  public abstract Address mapToAddress(AddressProto address);

  // from object to proto
  public abstract AddressProto mapAddressToProto(Address address);
}

proto message AddressProto (after the slash for each field, I wrote in which class field it needs to be mapped):

message AddressProto {
    string value = 1;               // Address.AddressValue.value
    string unrestricted_value = 2;  // Address.AddressValue.unrestrictedValue
    string country = 3;             // Address.Structure.Country.name
    string country_iso_code = 4;    // Address.Structure.Country.isoCode
    string region = 5;              // Address.Structure.Region.name
}

java class Address:

public class Address {
    public final AddressValue value;
    public final Structure structure;


    public static class AddressValue {
        public final String value;
        public final String unrestrictedValue;
    }


    public static class Structure {
        public final Country country;
        public final Region region;

        public static class Country {
            public final String name;
            public final String isoCode;
        }

        public static class Region {
            public final String name;
        }

    }
}
1 Answers

The solution turned out to be very simple. Even too much :) You just need to write your own implementation.

@Mapper(
    config = MapstructConfig.class,
    unmappedTargetPolicy = ReportingPolicy.ERROR
)
public interface AddressProtoMapper {
  default Address mapToAddress(AddressProto address){
    return new Address(
        ...
    );
  }

  default AddressProto mapAddressToProto(Address address) {
    return new AddressProto(
        ...
    );
  }
}
Related