001//@formatter:off 002/* 003 * Customer Mapper - demonstrates MAPPER pattern 004 * Code-Beispiel zum Buch Patterns Kompakt, Verlag Springer Vieweg 005 * Copyright 2014 Karl Eilebrecht 006 * 007 * Licensed under the Apache License, Version 2.0 (the "License"): 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019//@formatter:on 020package de.calamanari.pk.mapper; 021 022import java.util.Date; 023 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027import de.calamanari.pk.mapper.firstsys.Address; 028import de.calamanari.pk.mapper.firstsys.Person; 029import de.calamanari.pk.mapper.secondsys.Customer; 030import de.calamanari.pk.util.TimeUtils; 031 032/** 033 * Customer Mapper - demonstrates MAPPER pattern<br> 034 * In the first subsystem there exists a Person entity and an address entity.<br> 035 * For some reason in a second subsystem a Customer entity exists including address information.<br> 036 * This mapper is responsible for transparently mapping data between the two without giving one subsystem any knowledge of the other one.<br> 037 * Neither of the subsystems is aware of the mapper. 038 * 039 * @author <a href="mailto:Karl.Eilebrecht(a/t)calamanari.de">Karl Eilebrecht</a> 040 */ 041public class CustomerMapper extends AbstractMapper { 042 043 private static final Logger LOGGER = LoggerFactory.getLogger(CustomerMapper.class); 044 045 /** 046 * customer reference 047 */ 048 private final Customer customer; 049 050 /** 051 * address reference 052 */ 053 private final Address address; 054 055 /** 056 * person reference 057 */ 058 private final Person person; 059 060 /** 061 * Creates new customer mapper for the two entities from the first subsystem and the customer entity from the second subsystem 062 * 063 * @param person the person to be mapped 064 * @param address the address to be mapped 065 * @param customer the customer to be mapped 066 */ 067 public CustomerMapper(Person person, Address address, Customer customer) { 068 LOGGER.debug("{} created", this.getClass().getSimpleName()); 069 this.person = person; 070 this.address = address; 071 this.customer = customer; 072 } 073 074 @Override 075 public void map() { 076 LOGGER.debug("{}.map() called", this.getClass().getSimpleName()); 077 078 LOGGER.debug("Mapping data from subsystem1 (Person+Address) to subsystem2 structure (Customer[customerId='{}'])", customer.getCustomerId()); 079 customer.setFirstName(person.getFirstName()); 080 customer.setLastName(person.getLastName()); 081 082 // a common task of a (data) mapper is to handle structural differences 083 int customerLifeTimeDays = 0; 084 Date firstOrderDate = person.getFirstOrderDate(); 085 if (firstOrderDate != null) { 086 customerLifeTimeDays = TimeUtils.dayDiff(firstOrderDate, new Date(System.currentTimeMillis())); 087 } 088 customer.setCustomerLifeTimeDays(customerLifeTimeDays); 089 090 customer.setStreet(address.getStreet()); 091 customer.setZipCode(address.getZipCode()); 092 customer.setCity(address.getCity()); 093 } 094 095 @Override 096 public void mapBack() { 097 LOGGER.debug("{}.mapBack() called", this.getClass().getSimpleName()); 098 099 LOGGER.debug("Mapping data from subsystem2 (Customer[customerId='{}']) back to subsystem1 structures (Person+Address)", customer.getCustomerId()); 100 101 // here a merge strategy could be placed as there might 102 // be scenarios allowing concurrent changes in both subsystems 103 104 person.setFirstName(customer.getFirstName()); 105 person.setLastName(customer.getLastName()); 106 107 // in some cases not all information can/should be mapped back 108 // here the customer lifetime cannot be changed 109 110 address.setStreet(customer.getStreet()); 111 address.setZipCode(customer.getZipCode()); 112 address.setCity(customer.getCity()); 113 114 } 115 116}