Reputation: 1
I am using www.modelmapper.org and I am working on mapping the same "flat" java DTO into several "hierarchical" DTO.
The "flat" DTO has a number of primitive properties.
The "hierarchical" have a number of complex types that hold a number of primitive types. These DTOs are very similar, but not the same.
"Flat" DTO:
class TransactionRequest
{
String cashierNumber;
Long amount;
Integer currency;
public String getCashierNumber {..
...
}
"Hierarchical DTOs:
class PurchaseRequest
{
POSInfo posInfo;
Amount amount;
...
public PosInfo getPosInfo {..
public Amount getAmount { ..
...
}
class CancelRequest
{
POSInfo posInfo;
Amount amount;
...
public PosInfo getPosInfo {..
public Amount getAmount { ..
...
}
class Amount
{
BigDecimal value;
Integer currency;
public Integer getCurrency{..
...
}
class PosInfo
{
String cashierNumber;
public String getCashierNumber {..
}
TransactionRequest should be mapped into 1) PurchaseRequest and 2) CancelRequest.
One of the problems is, that the amount has to converted from Long (in minor unit) to a BigDecimal (in major unit with decimal digits). I achieved this by writing my own Long to BigDecimal converter. Now I have the problem to define the mappings required in a reusable fashion. What I don't want is to define the mappings for each target type like this:
class PurchaseMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}
class CancelMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}
I would like to have to only one time define the mapping of the Amount DTO (and all other sub type mappings such as PosInfo and many more) and then re-use these mappings. I tried several options:
The first thing I tried was declaring a mapping for TransactionRequest to Amount DTO in my ModelMapper. First, I assumed that simply declaring this mapping would be enough for the mapping mechanism to be also picked up when mapping a TransactionRequest to a PurchaseRequest. That however is not the case.
The second thing I tried does work, but seems to be overly complicated:
Here is the code:
public class AmountMap extends PropertyMap<TransactionRequest , Amount>
{
....
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
}
...
}
}
public class TransactionRequestToAmountConverter extends AbstractConverter<TransactionRequest, Amount>
{
private final ModelMapper mapper;
public TransactionRequestToAmountConverter(ModelMapper mapper)
{
this.mapper = mapper;
}
public Amount convert(TransactionRequest transactionRequest)
{
return mapper.map(transactionRequest, Amount.class);
}
}
public class PurchaseRequestMap extends PropertyMap<TransactionRequest, PurchaseRequest>
{
private final ModelMapper mapper;
public PurchaseRequestMap(ModelMapper mapper)
{
this.mapper = mapper;
}
protected void configure()
{
using(new TransactionRequestToAmountConverter(mapper)).map(source).setAmount(null);
...
}
}
Is there anybody out there that knows a simpler approach to this?
Upvotes: 0
Views: 1641
Reputation: 5107
Try mapping Long
to Amount
by itself:
modelMapper.createTypeMap(Long.class, Amount.class).setConverter(new Converter<Long, Amount>() {
//... convert Long to Amount
});
That mapping will then be used in your other types and should eliminate the need for the other stuff (if I'm reading your types correctly).
Upvotes: 0